packages feed

tidal-link 1.2.1 → 1.2.2

raw patch · 909 files changed

+52419/−40898 lines, 909 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

link/examples/linkaudio/AudioEngine.hpp view
@@ -21,22 +21,15 @@  // Make sure to define this before <cmath> is included for Windows #define _USE_MATH_DEFINES-#include <array>+#include <ableton/Link.hpp> #include <atomic>-#include <iostream>-#include <math.h> #include <mutex>-#include <vector> -#include "AudioPlatform.hpp"-#include "LinkAudioRenderer.hpp"- namespace ableton { namespace linkaudio { -template <typename Link> class AudioEngine { public:@@ -51,46 +44,38 @@   bool isStartStopSyncEnabled() const;   void setStartStopSyncEnabled(bool enabled); +private:   struct EngineData   {-    double requestedTempo = 0;-    bool requestStart = false;-    bool requestStop = false;-    double quantum = 4;-    bool startStopSyncOn = false;-  };--  struct EngineDataSignals-  {-    std::atomic<double> requestedTempo{0};-    std::atomic<bool> requestStart{false};-    std::atomic<bool> requestStop{false};-    std::atomic<double> quantum{4};-    std::atomic<bool> startStopSyncOn{false};+    double requestedTempo;+    bool requestStart;+    bool requestStop;+    double quantum;+    bool startStopSyncOn;   }; --  void setNumFrames(std::size_t size);+  void setBufferSize(std::size_t size);   void setSampleRate(double sampleRate);   EngineData pullEngineData();-  void renderMetronomeIntoBuffer(typename Link::SessionState sessionState,-                                 double quantum,-                                 std::chrono::microseconds beginHostTime,-                                 std::size_t numSamples);-  void audioCallback(std::chrono::microseconds hostTime, std::size_t numSamples);+  void renderMetronomeIntoBuffer(Link::SessionState sessionState,+    double quantum,+    std::chrono::microseconds beginHostTime,+    std::size_t numSamples);+  void audioCallback(const std::chrono::microseconds hostTime, std::size_t numSamples);    Link& mLink;   double mSampleRate;   std::atomic<std::chrono::microseconds> mOutputLatency;-  std::array<std::vector<double>, 2> mBuffers;-  EngineDataSignals mEngineDataSignals;+  std::vector<double> mBuffer;+  EngineData mSharedEngineData;+  EngineData mLockfreeEngineData;   std::chrono::microseconds mTimeAtLastClick;   bool mIsPlaying;+  std::mutex mEngineDataGuard; -  LinkAudioRenderer<Link> mLinkAudioRenderer;+  friend class AudioPlatform; }; + } // namespace linkaudio } // namespace ableton--#include "AudioEngine.ipp"
− link/examples/linkaudio/AudioEngine.ipp
@@ -1,255 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--// Make sure to define this before <cmath> is included for-// Wihttps://github.com/AbletonAppDev/link/pull/664ndows-#ifdef LINK_PLATFORM_WINDOWS-#define _USE_MATH_DEFINES-#endif-#include <cmath>-#include <iostream>--namespace ableton-{-namespace linkaudio-{--template <typename Link>-AudioEngine<Link>::AudioEngine(Link& link)-  : mLink(link)-  , mSampleRate(44100.)-  , mOutputLatency(std::chrono::microseconds{0})-  , mTimeAtLastClick{}-  , mIsPlaying(false)-  , mLinkAudioRenderer(mLink, mSampleRate)-{-  if (!mOutputLatency.is_lock_free())-  {-    std::cout << "WARNING: AudioEngine::mOutputLatency is not lock free!" << std::endl;-  }-}--template <typename Link>-void AudioEngine<Link>::startPlaying()-{-  mEngineDataSignals.requestStart = true;-}--template <typename Link>-void AudioEngine<Link>::stopPlaying()-{-  mEngineDataSignals.requestStop = true;-}--template <typename Link>-bool AudioEngine<Link>::isPlaying() const-{-  return mLink.captureAppSessionState().isPlaying();-}--template <typename Link>-double AudioEngine<Link>::beatTime() const-{-  const auto sessionState = mLink.captureAppSessionState();-  return sessionState.beatAtTime(mLink.clock().micros(), mEngineDataSignals.quantum);-}--template <typename Link>-void AudioEngine<Link>::setTempo(double tempo)-{-  mEngineDataSignals.requestedTempo = tempo;-}--template <typename Link>-double AudioEngine<Link>::quantum() const-{-  return mEngineDataSignals.quantum;-}--template <typename Link>-void AudioEngine<Link>::setQuantum(double quantum)-{-  mEngineDataSignals.quantum = quantum;-}--template <typename Link>-bool AudioEngine<Link>::isStartStopSyncEnabled() const-{-  return mLink.isStartStopSyncEnabled();-}--template <typename Link>-void AudioEngine<Link>::setStartStopSyncEnabled(const bool enabled)-{-  mLink.enableStartStopSync(enabled);-}--template <typename Link>-void AudioEngine<Link>::setNumFrames(std::size_t size)-{-  mBuffers[0] = std::vector<double>(size, 0.);-  mBuffers[1] = std::vector<double>(size, 0.);-}--template <typename Link>-void AudioEngine<Link>::setSampleRate(double sampleRate)-{-  mSampleRate = sampleRate;-}--template <typename Link>-typename AudioEngine<Link>::EngineData AudioEngine<Link>::pullEngineData()-{-  auto engineData = EngineData{};--  engineData.requestedTempo = mEngineDataSignals.requestedTempo.exchange(0.);-  engineData.requestStart = mEngineDataSignals.requestStart.exchange(false);-  engineData.requestStop = mEngineDataSignals.requestStop.exchange(false);-  engineData.startStopSyncOn = mEngineDataSignals.startStopSyncOn.load();-  engineData.quantum = mEngineDataSignals.quantum.load();--  return engineData;-}--template <typename Link>-void AudioEngine<Link>::renderMetronomeIntoBuffer(-  const typename Link::SessionState sessionState,-  const double quantum,-  const std::chrono::microseconds beginHostTime,-  const std::size_t numSamples)-{-  using namespace std::chrono;--  // Metronome frequencies-  static const double highTone = 1567.98;-  static const double lowTone = 1108.73;-  // 100ms click duration-  static const auto clickDuration = duration<double>{0.1};--  // The number of microseconds that elapse between samples-  const auto microsPerSample = 1e6 / mSampleRate;--  for (std::size_t i = 0; i < numSamples; ++i)-  {-    double amplitude = 0.;-    // Compute the host time for this sample and the last.-    const auto hostTime =-      beginHostTime + microseconds(llround(static_cast<double>(i) * microsPerSample));-    const auto lastSampleHostTime = hostTime - microseconds(llround(microsPerSample));--    // Only make sound for positive beat magnitudes. Negative beat-    // magnitudes are count-in beats.-    if (sessionState.beatAtTime(hostTime, quantum) >= 0.)-    {-      // If the phase wraps around between the last sample and the-      // current one with respect to a 1 beat quantum, then a click-      // should occur.-      if (sessionState.phaseAtTime(hostTime, 1)-          < sessionState.phaseAtTime(lastSampleHostTime, 1))-      {-        mTimeAtLastClick = hostTime;-      }--      const auto secondsAfterClick =-        duration_cast<duration<double>>(hostTime - mTimeAtLastClick);--      // If we're within the click duration of the last beat, render-      // the click tone into this sample-      if (secondsAfterClick < clickDuration)-      {-        // If the phase of the last beat with respect to the current-        // quantum was zero, then it was at a quantum boundary and we-        // want to use the high tone. For other beats within the-        // quantum, use the low tone.-        const auto freq =-          floor(sessionState.phaseAtTime(hostTime, quantum)) == 0 ? highTone : lowTone;--        // Simple cosine synth-        amplitude = cos(2 * M_PI * secondsAfterClick.count() * freq)-                    * (1 - sin(5 * M_PI * secondsAfterClick.count()));-      }-    }-    mBuffers[0][i] = amplitude;-  }-}--template <typename Link>-void AudioEngine<Link>::audioCallback(const std::chrono::microseconds hostTime,-                                      const std::size_t numSamples)-{-  const auto engineData = pullEngineData();--  auto sessionState = mLink.captureAudioSessionState();--  // Clear the buffer-  for (auto& buffer : mBuffers)-  {-    std::fill(buffer.begin(), buffer.end(), 0);-  }--  if (engineData.requestStart)-  {-    sessionState.setIsPlaying(true, hostTime);-  }--  if (engineData.requestStop)-  {-    sessionState.setIsPlaying(false, hostTime);-  }--  if (!mIsPlaying && sessionState.isPlaying())-  {-    // Reset the timeline so that beat 0 corresponds to the time when transport starts-    sessionState.requestBeatAtStartPlayingTime(0, engineData.quantum);-    mIsPlaying = true;-  }-  else if (mIsPlaying && !sessionState.isPlaying())-  {-    mIsPlaying = false;-  }--  if (engineData.requestedTempo > 0)-  {-    // Set the newly requested tempo from the beginning of this buffer-    sessionState.setTempo(engineData.requestedTempo, hostTime);-  }--  // Timeline modifications are complete, commit the results-  mLink.commitAudioSessionState(sessionState);--  if (mIsPlaying)-  {-    // As long as the engine is playing, generate metronome clicks in-    // the buffer at the appropriate beats.-    renderMetronomeIntoBuffer(sessionState, engineData.quantum, hostTime, numSamples);-  }--  mLinkAudioRenderer(mBuffers[0].data(),-                     mBuffers[1].data(),-                     mBuffers[0].size(),-                     sessionState,-                     mSampleRate,-                     hostTime,-                     engineData.quantum);-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_Asio.hpp view
@@ -21,6 +21,7 @@  #include "AudioEngine.hpp" +#include <ableton/Link.hpp> #include <ableton/link/HostTimeFilter.hpp>  #include "asiosys.h" // Should be included before asio.h@@ -66,13 +67,9 @@ void fatalError(const ASIOError result, const std::string& function); double asioSamplesToDouble(const ASIOSamples& samples); -template <typename Link> ASIOTime* bufferSwitchTimeInfo(ASIOTime* timeInfo, long index, ASIOBool);--template <typename Link> void bufferSwitch(long index, ASIOBool processNow); -template <typename Link> class AudioPlatform { public:@@ -81,8 +78,13 @@    void audioCallback(ASIOTime* timeInfo, long index); -  AudioEngine<Link> mEngine;+  AudioEngine mEngine; +  // Unfortunately, the ASIO SDK does not allow passing void* user data to callback+  // functions, so we need to keep a singleton instance of the audio engine+  static AudioPlatform* singleton();+  static void setSingleton(AudioPlatform* platform);+ private:   void createAsioBuffers();   void initializeDriverInfo();@@ -92,13 +94,10 @@    DriverInfo mDriverInfo;   ASIOCallbacks mAsioCallbacks;-  link::HostTimeFilter<typename Link::Clock> mHostTimeFilter;+  link::HostTimeFilter<platforms::windows::Clock> mHostTimeFilter; -public:-  static AudioPlatform<Link>* _singleton;+  static AudioPlatform* _singleton; };  } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_Asio.ipp"
− link/examples/linkaudio/AudioPlatform_Asio.ipp
@@ -1,319 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--namespace ableton-{-namespace linkaudio-{--static void* SINGLETON = nullptr;--void fatalError(const ASIOError result, const std::string& function)-{-  std::cerr << "Call to ASIO function " << function << " failed";-  if (result != ASE_OK)-  {-    std::cerr << " (ASIO error code " << result << ")";-  }-  std::cerr << std::endl;-  std::terminate();-}--double asioSamplesToDouble(const ASIOSamples& samples)-{-  return samples.lo + samples.hi * std::pow(2, 32);-}--// ASIO processing callbacks-template <typename Link>-ASIOTime* bufferSwitchTimeInfo(ASIOTime* timeInfo, long index, ASIOBool)-{-  AudioPlatform<Link>* platform =-    static_cast<AudioPlatform<Link>*>(SINGLETON); // AudioPlatform<Link>::_singleton;-  if (platform)-  {-    platform->audioCallback(timeInfo, index);-  }-  return nullptr;-}--template <typename Link>-void bufferSwitch(long index, ASIOBool processNow)-{-  ASIOTime timeInfo{};-  ASIOError result = ASIOGetSamplePosition(-    &timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime);-  if (result != ASE_OK)-  {-    std::cerr << "ASIOGetSamplePosition failed with ASIO error: " << result << std::endl;-  }-  else-  {-    timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;-  }--  bufferSwitchTimeInfo<Link>(&timeInfo, index, processNow);-}--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)-  : mEngine(link)-{-  initialize();-  mEngine.setNumFrames(mDriverInfo.preferredSize);-  mEngine.setSampleRate(mDriverInfo.sampleRate);-  SINGLETON = this;-  start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform()-{-  stop();-  ASIODisposeBuffers();-  ASIOExit();-  if (asioDrivers != nullptr)-  {-    asioDrivers->removeCurrentDriver();-  }--  SINGLETON = nullptr;-}--template <typename Link>-void AudioPlatform<Link>::audioCallback(ASIOTime* timeInfo, long index)-{-  auto hostTime = std::chrono::microseconds(0);-  if (timeInfo->timeInfo.flags & kSystemTimeValid)-  {-    hostTime = mHostTimeFilter.sampleTimeToHostTime(-      asioSamplesToDouble(timeInfo->timeInfo.samplePosition));-  }--  const auto bufferBeginAtOutput = hostTime + mEngine.mOutputLatency.load();---  ASIOBufferInfo* bufferInfos = mDriverInfo.bufferInfos;-  const long numSamples = mDriverInfo.preferredSize;-  const long numChannels = mDriverInfo.numBuffers;-  const double maxAmp = std::numeric_limits<int>::max();--  mEngine.audioCallback(bufferBeginAtOutput, numSamples);--  for (long i = 0; i < numSamples; ++i)-  {-    for (long j = 0; j < numChannels; ++j)-    {-      int* buffer = static_cast<int*>(bufferInfos[j].buffers[index]);-      buffer[i] = static_cast<int>(mEngine.mBuffers[j][i] * maxAmp);-    }-  }--  if (mDriverInfo.outputReady)-  {-    ASIOOutputReady();-  }-}--template <typename Link>-void AudioPlatform<Link>::createAsioBuffers()-{-  DriverInfo& driverInfo = mDriverInfo;-  ASIOBufferInfo* bufferInfo = driverInfo.bufferInfos;-  driverInfo.numBuffers = 0;--  // Prepare input channels. Though this is not necessarily required, the opened input-  // channels will not work.-  int numInputBuffers;-  if (driverInfo.inputChannels > LINK_ASIO_INPUT_CHANNELS)-  {-    numInputBuffers = LINK_ASIO_INPUT_CHANNELS;-  }-  else-  {-    numInputBuffers = driverInfo.inputChannels;-  }--  for (long i = 0; i < numInputBuffers; ++i, ++bufferInfo)-  {-    bufferInfo->isInput = ASIOTrue;-    bufferInfo->channelNum = i;-    bufferInfo->buffers[0] = bufferInfo->buffers[1] = nullptr;-  }--  // Prepare output channels-  int numOutputBuffers;-  if (driverInfo.outputChannels > LINK_ASIO_OUTPUT_CHANNELS)-  {-    numOutputBuffers = LINK_ASIO_OUTPUT_CHANNELS;-  }-  else-  {-    numOutputBuffers = driverInfo.outputChannels;-  }--  for (long i = 0; i < numOutputBuffers; i++, bufferInfo++)-  {-    bufferInfo->isInput = ASIOFalse;-    bufferInfo->channelNum = i;-    bufferInfo->buffers[0] = bufferInfo->buffers[1] = nullptr;-  }--  driverInfo.numBuffers = numInputBuffers + numOutputBuffers;-  ASIOError result = ASIOCreateBuffers(driverInfo.bufferInfos,-                                       driverInfo.numBuffers,-                                       driverInfo.preferredSize,-                                       &(mAsioCallbacks));-  if (result != ASE_OK)-  {-    fatalError(result, "ASIOCreateBuffers");-  }--  // Now get all buffer details, sample word length, name, word clock group and latency-  for (long i = 0; i < driverInfo.numBuffers; ++i)-  {-    driverInfo.channelInfos[i].channel = driverInfo.bufferInfos[i].channelNum;-    driverInfo.channelInfos[i].isInput = driverInfo.bufferInfos[i].isInput;--    result = ASIOGetChannelInfo(&driverInfo.channelInfos[i]);-    if (result != ASE_OK)-    {-      fatalError(result, "ASIOGetChannelInfo");-    }--    std::clog << "ASIOGetChannelInfo successful, type: "-              << (driverInfo.bufferInfos[i].isInput ? "input" : "output")-              << ", channel: " << i-              << ", sample type: " << driverInfo.channelInfos[i].type << std::endl;--    if (driverInfo.channelInfos[i].type != ASIOSTInt32LSB)-    {-      fatalError(ASE_OK, "Unsupported sample type!");-    }-  }--  long inputLatency, outputLatency;-  result = ASIOGetLatencies(&inputLatency, &outputLatency);-  if (result != ASE_OK)-  {-    fatalError(result, "ASIOGetLatencies");-  }-  std::clog << "Driver input latency: " << inputLatency << "usec"-            << ", output latency: " << outputLatency << "usec" << std::endl;--  const double bufferSize = driverInfo.preferredSize / driverInfo.sampleRate;-  auto outputLatencyMicros =-    std::chrono::microseconds(llround(outputLatency / driverInfo.sampleRate));-  outputLatencyMicros += std::chrono::microseconds(llround(1.0e6 * bufferSize));--  mEngine.mOutputLatency.store(outputLatencyMicros);--  std::clog << "Total latency: " << outputLatencyMicros.count() << "usec" << std::endl;-}--template <typename Link>-void AudioPlatform<Link>::initializeDriverInfo()-{-  ASIOError result =-    ASIOGetChannels(&mDriverInfo.inputChannels, &mDriverInfo.outputChannels);-  if (result != ASE_OK)-  {-    fatalError(result, "ASIOGetChannels");-  }-  std::clog << "ASIOGetChannels succeeded, inputs:" << mDriverInfo.inputChannels-            << ", outputs: " << mDriverInfo.outputChannels << std::endl;--  long minSize, maxSize, granularity;-  result =-    ASIOGetBufferSize(&minSize, &maxSize, &mDriverInfo.preferredSize, &granularity);-  if (result != ASE_OK)-  {-    fatalError(result, "ASIOGetBufferSize");-  }-  std::clog << "ASIOGetBufferSize succeeded, min: " << minSize << ", max: " << maxSize-            << ", preferred: " << mDriverInfo.preferredSize-            << ", granularity: " << granularity << std::endl;--  result = ASIOGetSampleRate(&mDriverInfo.sampleRate);-  if (result != ASE_OK)-  {-    fatalError(result, "ASIOGetSampleRate");-  }-  std::clog << "ASIOGetSampleRate succeeded, sampleRate: " << mDriverInfo.sampleRate-            << "Hz" << std::endl;--  // Check wether the driver requires the ASIOOutputReady() optimization, which can be-  // used by the driver to reduce output latency by one block-  mDriverInfo.outputReady = (ASIOOutputReady() == ASE_OK);-  std::clog << "ASIOOutputReady optimization is "-            << (mDriverInfo.outputReady ? "enabled" : "disabled") << std::endl;-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{-  if (!loadAsioDriver(LINK_ASIO_DRIVER_NAME))-  {-    std::cerr << "Failed opening ASIO driver for device named '" << LINK_ASIO_DRIVER_NAME-              << "', is the driver installed?" << std::endl;-    std::terminate();-  }--  ASIOError result = ASIOInit(&mDriverInfo.driverInfo);-  if (result != ASE_OK)-  {-    fatalError(result, "ASIOInit");-  }--  std::clog << "ASIOInit succeeded, asioVersion: " << mDriverInfo.driverInfo.asioVersion-            << ", driverVersion: " << mDriverInfo.driverInfo.driverVersion-            << ", name: " << mDriverInfo.driverInfo.name << std::endl;--  initializeDriverInfo();--  ASIOCallbacks* callbacks = &(mAsioCallbacks);-  callbacks->bufferSwitch = &bufferSwitch<Link>;-  callbacks->bufferSwitchTimeInfo = &bufferSwitchTimeInfo<Link>;-  createAsioBuffers();-}--template <typename Link>-void AudioPlatform<Link>::start()-{-  ASIOError result = ASIOStart();-  if (result != ASE_OK)-  {-    fatalError(result, "ASIOStart");-  }-}--template <typename Link>-void AudioPlatform<Link>::stop()-{-  ASIOError result = ASIOStop();-  if (result != ASE_OK)-  {-    fatalError(result, "ASIOStop");-  }-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_CoreAudio.hpp view
@@ -27,27 +27,20 @@ namespace linkaudio { -template <typename Link> class AudioPlatform { public:   AudioPlatform(Link& link);   ~AudioPlatform();-  AudioEngine<Link> mEngine;+  AudioEngine mEngine;  private:   static OSStatus audioCallback(void* inRefCon,-                                AudioUnitRenderActionFlags*,-                                const AudioTimeStamp* inTimeStamp,-                                UInt32,-                                UInt32 inNumberFrames,-                                AudioBufferList* ioData);--  static void streamFormatCallback(void* inRefCon,-                                   AudioUnit inUnit,-                                   AudioUnitPropertyID inID,-                                   AudioUnitScope inScope,-                                   AudioUnitElement inElement);+    AudioUnitRenderActionFlags*,+    const AudioTimeStamp* inTimeStamp,+    UInt32,+    UInt32 inNumberFrames,+    AudioBufferList* ioData);    void initialize();   void uninitialize();@@ -59,5 +52,3 @@  } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_CoreAudio.ipp"
− link/examples/linkaudio/AudioPlatform_CoreAudio.ipp
@@ -1,294 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#include "AudioPlatform_CoreAudio.hpp"-#include <chrono>-#include <iostream>-#include <mach/mach_time.h>--namespace ableton-{-namespace linkaudio-{--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)-  : mEngine(link)-{-  initialize();-  start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform()-{-  stop();-  uninitialize();-}--template <typename Link>-OSStatus AudioPlatform<Link>::audioCallback(void* inRefCon,-                                            AudioUnitRenderActionFlags*,-                                            const AudioTimeStamp* inTimeStamp,-                                            UInt32,-                                            UInt32 inNumberFrames,-                                            AudioBufferList* ioData)-{-  auto engine = static_cast<AudioEngine<Link>*>(inRefCon);--  const auto bufferBeginAtOutput =-    engine->mLink.clock().ticksToMicros(inTimeStamp->mHostTime)-    + engine->mOutputLatency.load();--  engine->audioCallback(bufferBeginAtOutput, inNumberFrames);--  for (std::size_t i = 0; i < inNumberFrames; ++i)-  {-    for (UInt32 j = 0; j < ioData->mNumberBuffers; ++j)-    {-      auto bufData = static_cast<SInt16*>(ioData->mBuffers[j].mData);-      bufData[i] = static_cast<SInt16>(32761. * engine->mBuffers[j][i]);-    }-  }--  return noErr;-}--template <typename Link>-void AudioPlatform<Link>::streamFormatCallback(void* inRefCon,-                                               AudioUnit inUnit,-                                               AudioUnitPropertyID inID,-                                               AudioUnitScope inScope,-                                               AudioUnitElement inElement)-{-#pragma unused(inID)-  if (inScope == kAudioUnitScope_Output && inElement == 0)-  {-    AudioStreamBasicDescription asbd;-    UInt32 dataSize = sizeof(asbd);-    OSStatus result = AudioUnitGetProperty(inUnit,-                                           kAudioUnitProperty_StreamFormat,-                                           kAudioUnitScope_Output,-                                           0,-                                           &asbd,-                                           &dataSize);-    if (result)-    {-      std::cerr << "Could not get Audio Unit stream format. " << result << std::endl;-    }--    auto pPlatform = static_cast<AudioPlatform<Link>*>(inRefCon);-    const Float64 oldSampleRate = pPlatform->mEngine.mSampleRate;-    if (fabs(oldSampleRate - asbd.mSampleRate) > 1.)-    {-      std::cout << "CORE AUDIO STREAM FORMAT CHANGED: " << asbd.mSampleRate << std::endl;-      pPlatform->stop();-      pPlatform->uninitialize();-      pPlatform->mEngine.setSampleRate(asbd.mSampleRate);-      pPlatform->initialize();-      pPlatform->start();-    }-  }-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{-  AudioComponentDescription cd = {};-  cd.componentManufacturer = kAudioUnitManufacturer_Apple;-  cd.componentFlags = 0;-  cd.componentFlagsMask = 0;-  cd.componentType = kAudioUnitType_Output;-  cd.componentSubType = kAudioUnitSubType_DefaultOutput;--  AudioComponent component = AudioComponentFindNext(nullptr, &cd);-  OSStatus result = AudioComponentInstanceNew(component, &mIoUnit);-  if (result)-  {-    std::cerr << "Could not get Audio Unit. " << result << std::endl;-    std::terminate();-  }--  UInt32 size = sizeof(mEngine.mSampleRate);-  result = AudioUnitGetProperty(mIoUnit,-                                kAudioUnitProperty_SampleRate,-                                kAudioUnitScope_Output,-                                0,-                                &mEngine.mSampleRate,-                                &size);-  if (result)-  {-    std::cerr << "Could not get sample rate. " << result << std::endl;-    std::terminate();-  }-  std::clog << "SAMPLE RATE: " << mEngine.mSampleRate << std::endl;--  AudioStreamBasicDescription asbd = {};-  asbd.mFormatID = kAudioFormatLinearPCM;-  asbd.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked-                      | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsNonInterleaved;-  asbd.mChannelsPerFrame = 2;-  asbd.mBytesPerPacket = sizeof(SInt16);-  asbd.mFramesPerPacket = 1;-  asbd.mBytesPerFrame = sizeof(SInt16);-  asbd.mBitsPerChannel = 8 * sizeof(SInt16);-  asbd.mSampleRate = mEngine.mSampleRate;--  result = AudioUnitSetProperty(mIoUnit,-                                kAudioUnitProperty_StreamFormat,-                                kAudioUnitScope_Input,-                                0,-                                &asbd,-                                sizeof(asbd));-  if (result)-  {-    std::cerr << "Could not set stream format. " << result << std::endl;-  }--  result = AudioUnitAddPropertyListener(-    mIoUnit, kAudioUnitProperty_StreamFormat, streamFormatCallback, this);-  if (result)-  {-    std::cerr << "Could not add listener to stream format changes. " << result-              << std::endl;-  }--  char deviceName[512];-  size = sizeof(deviceName);-  result = AudioUnitGetProperty(mIoUnit,-                                kAudioDevicePropertyDeviceName,-                                kAudioUnitScope_Global,-                                0,-                                &deviceName,-                                &size);-  if (result)-  {-    std::cerr << "Could not get device name. " << result << std::endl;-    std::terminate();-  }-  std::clog << "DEVICE NAME: " << deviceName << std::endl;--  UInt32 numFrames = 512;-  size = sizeof(numFrames);-  result = AudioUnitSetProperty(mIoUnit,-                                kAudioDevicePropertyBufferFrameSize,-                                kAudioUnitScope_Global,-                                0,-                                &numFrames,-                                size);-  if (result)-  {-    std::cerr << "Could not set num frames. " << result << std::endl;-    std::terminate();-  }-  mEngine.setNumFrames(numFrames);--  UInt32 propertyResult = 0;-  size = sizeof(propertyResult);-  result = AudioUnitGetProperty(mIoUnit,-                                kAudioDevicePropertyBufferFrameSize,-                                kAudioUnitScope_Global,-                                0,-                                &propertyResult,-                                &size);-  if (result)-  {-    std::cerr << "Could not get buffer size. " << result << std::endl;-    std::terminate();-  }-  std::clog << "BUFFER SIZE: " << propertyResult << " samples, "-            << propertyResult / mEngine.mSampleRate * 1e3 << " ms." << std::endl;--  // the buffer, stream and safety-offset latencies are part of inTimeStamp->mHostTime-  // within the audio callback.-  UInt32 deviceLatency = 0;-  size = sizeof(deviceLatency);-  result = AudioUnitGetProperty(mIoUnit,-                                kAudioDevicePropertyLatency,-                                kAudioUnitScope_Output,-                                0,-                                &deviceLatency,-                                &size);-  if (result)-  {-    std::cerr << "Could not get output device latency. " << result << std::endl;-    std::terminate();-  }-  std::clog << "OUTPUT DEVICE LATENCY: " << deviceLatency << " samples, "-            << deviceLatency / mEngine.mSampleRate * 1e3 << " ms." << std::endl;--  using namespace std::chrono;-  const auto latency = static_cast<double>(deviceLatency) / mEngine.mSampleRate;-  mEngine.mOutputLatency.store(duration_cast<microseconds>(duration<double>{latency}));--  AURenderCallbackStruct ioRemoteInput;-  ioRemoteInput.inputProc = audioCallback;-  ioRemoteInput.inputProcRefCon = &mEngine;--  result = AudioUnitSetProperty(mIoUnit,-                                kAudioUnitProperty_SetRenderCallback,-                                kAudioUnitScope_Input,-                                0,-                                &ioRemoteInput,-                                sizeof(ioRemoteInput));-  if (result)-  {-    std::cerr << "Could not set render callback. " << result << std::endl;-  }--  result = AudioUnitInitialize(mIoUnit);-  if (result)-  {-    std::cerr << "Could not initialize audio unit. " << result << std::endl;-  }-}--template <typename Link>-void AudioPlatform<Link>::uninitialize()-{-  OSStatus result = AudioUnitUninitialize(mIoUnit);-  if (result)-  {-    std::cerr << "Could not uninitialize Audio Unit. " << result << std::endl;-  }-}--template <typename Link>-void AudioPlatform<Link>::start()-{-  OSStatus result = AudioOutputUnitStart(mIoUnit);-  if (result)-  {-    std::cerr << "Could not start Audio Unit. " << result << std::endl;-    std::terminate();-  }-}--template <typename Link>-void AudioPlatform<Link>::stop()-{-  OSStatus result = AudioOutputUnitStop(mIoUnit);-  if (result)-  {-    std::cerr << "Could not stop Audio Unit. " << result << std::endl;-  }-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_Dummy.hpp view
@@ -19,14 +19,13 @@  #pragma once -#include <chrono>+#include <ableton/Link.hpp>  namespace ableton { namespace linkaudio { -template <typename Link> class AudioPlatform {   class AudioEngine@@ -52,7 +51,10 @@       mLink.commitAppSessionState(sessionState);     } -    bool isPlaying() const { return mLink.captureAppSessionState().isPlaying(); }+    bool isPlaying() const+    {+      return mLink.captureAppSessionState().isPlaying();+    }      double beatTime() const     {@@ -67,16 +69,31 @@       mLink.commitAppSessionState(sessionState);     } -    double quantum() const { return mQuantum; }+    double quantum() const+    {+      return mQuantum;+    } -    void setQuantum(double quantum) { mQuantum = quantum; }+    void setQuantum(double quantum)+    {+      mQuantum = quantum;+    } -    bool isStartStopSyncEnabled() const { return mLink.isStartStopSyncEnabled(); }+    bool isStartStopSyncEnabled() const+    {+      return mLink.isStartStopSyncEnabled();+    } -    void setStartStopSyncEnabled(bool enabled) { mLink.enableStartStopSync(enabled); }+    void setStartStopSyncEnabled(bool enabled)+    {+      mLink.enableStartStopSync(enabled);+    }    private:-    std::chrono::microseconds now() const { return mLink.clock().micros(); }+    std::chrono::microseconds now() const+    {+      return mLink.clock().micros();+    }      Link& mLink;     double mQuantum;
link/examples/linkaudio/AudioPlatform_Jack.hpp view
@@ -21,6 +21,7 @@  #include "AudioEngine.hpp" #include <ableton/link/HostTimeFilter.hpp>+#include <ableton/platforms/Config.hpp> #include <jack/jack.h>  namespace ableton@@ -28,14 +29,13 @@ namespace linkaudio { -template <typename Link> class AudioPlatform { public:   AudioPlatform(Link& link);   ~AudioPlatform(); -  AudioEngine<Link> mEngine;+  AudioEngine mEngine;  private:   static int audioCallback(jack_nframes_t nframes, void* pvUserData);@@ -48,7 +48,7 @@   void start();   void stop(); -  link::HostTimeFilter<typename Link::Clock> mHostTimeFilter;+  link::HostTimeFilter<link::platform::Clock> mHostTimeFilter;   double mSampleTime;   jack_client_t* mpJackClient;   jack_port_t** mpJackPorts;@@ -56,5 +56,3 @@  } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_Jack.ipp"
− link/examples/linkaudio/AudioPlatform_Jack.ipp
@@ -1,221 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#include <chrono>-#include <iostream>-#include <string>--namespace ableton-{-namespace linkaudio-{--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)-  : mEngine(link)-  , mSampleTime(0.)-  , mpJackClient(nullptr)-  , mpJackPorts(nullptr)-{-  initialize();-  start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform<Link>()-{-  stop();-  uninitialize();-}--template <typename Link>-int AudioPlatform<Link>::audioCallback(jack_nframes_t nframes, void* pvUserData)-{-  auto pAudioPlatform = static_cast<AudioPlatform*>(pvUserData);-  return pAudioPlatform->audioCallback(nframes);-}--template <typename Link>-void AudioPlatform<Link>::latencyCallback(jack_latency_callback_mode_t, void* pvUserData)-{-  auto pAudioPlatform = static_cast<AudioPlatform*>(pvUserData);-  pAudioPlatform->updateLatency();-}--template <typename Link>-void AudioPlatform<Link>::updateLatency()-{-  jack_latency_range_t latencyRange;-  jack_port_get_latency_range(mpJackPorts[0], JackPlaybackLatency, &latencyRange);-  mEngine.mOutputLatency.store(-    std::chrono::microseconds(llround(1.0e6 * latencyRange.max / mEngine.mSampleRate)));-}--template <typename Link>-int AudioPlatform<Link>::audioCallback(jack_nframes_t nframes)-{-  using namespace std::chrono;-  AudioEngine<Link>& engine = mEngine;--  const auto hostTime = mHostTimeFilter.sampleTimeToHostTime(mSampleTime);--  mSampleTime += nframes;--  const auto bufferBeginAtOutput = hostTime + engine.mOutputLatency.load();--  engine.audioCallback(bufferBeginAtOutput, nframes);--  for (std::size_t k = 0; k < 2; ++k)-  {-    auto buffer = static_cast<float*>(jack_port_get_buffer(mpJackPorts[k], nframes));-    for (std::size_t i = 0; i < nframes; ++i)-    {-      buffer[i] = static_cast<float>(engine.mBuffers[k][i]);-    }-  }--  return 0;-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{-  jack_status_t status = JackFailure;-  mpJackClient = jack_client_open("LinkHut", JackNullOption, &status);-  if (mpJackClient == nullptr)-  {-    std::cerr << "Could not initialize Audio Engine. ";-    std::cerr << "JACK: " << std::endl;-    if (status & JackFailure)-    {-      std::cerr << "Overall operation failed." << std::endl;-    }-    if (status & JackInvalidOption)-    {-      std::cerr << "Invalid or unsupported option." << std::endl;-    }-    if (status & JackNameNotUnique)-    {-      std::cerr << "Client name not unique." << std::endl;-    }-    if (status & JackServerStarted)-    {-      std::cerr << "Server is started." << std::endl;-    }-    if (status & JackServerFailed)-    {-      std::cerr << "Unable to connect to server." << std::endl;-    }-    if (status & JackServerError)-    {-      std::cerr << "Server communication error." << std::endl;-    }-    if (status & JackNoSuchClient)-    {-      std::cerr << "Client does not exist." << std::endl;-    }-    if (status & JackLoadFailure)-    {-      std::cerr << "Unable to load internal client." << std::endl;-    }-    if (status & JackInitFailure)-    {-      std::cerr << "Unable to initialize client." << std::endl;-    }-    if (status & JackShmFailure)-    {-      std::cerr << "Unable to access shared memory." << std::endl;-    }-    if (status & JackVersionError)-    {-      std::cerr << "Client protocol version mismatch." << std::endl;-    }-    std::cerr << std::endl;-    std::terminate();-  }--  const double bufferSize = jack_get_buffer_size(mpJackClient);-  const double sampleRate = jack_get_sample_rate(mpJackClient);-  mEngine.setNumFrames(static_cast<std::size_t>(bufferSize));-  mEngine.setSampleRate(sampleRate);--  jack_set_latency_callback(mpJackClient, AudioPlatform::latencyCallback, this);--  mpJackPorts = new jack_port_t*[2];--  for (int k = 0; k < 2; ++k)-  {-    const std::string port_name = "out_" + std::to_string(k + 1);-    mpJackPorts[k] = jack_port_register(-      mpJackClient, port_name.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);-    if (mpJackPorts[k] == nullptr)-    {-      std::cerr << "Could not get Audio Device. " << std::endl;-      jack_client_close(mpJackClient);-      std::terminate();-    }-  }--  jack_set_process_callback(mpJackClient, AudioPlatform::audioCallback, this);-}--template <typename Link>-void AudioPlatform<Link>::uninitialize()-{-  for (int k = 0; k < 2; ++k)-  {-    jack_port_unregister(mpJackClient, mpJackPorts[k]);-    mpJackPorts[k] = nullptr;-  }-  delete[] mpJackPorts;-  mpJackPorts = nullptr;--  jack_client_close(mpJackClient);-  mpJackClient = nullptr;-}--template <typename Link>-void AudioPlatform<Link>::start()-{-  jack_activate(mpJackClient);--  const char** playback_ports = jack_get_ports(-    mpJackClient, nullptr, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsPhysical);--  if (playback_ports)-  {-    const std::string client_name = jack_get_client_name(mpJackClient);-    for (int k = 0; k < 2; ++k)-    {-      const std::string port_name = "out_" + std::to_string(k + 1);-      const std::string client_port = client_name + ':' + port_name;-      jack_connect(mpJackClient, client_port.c_str(), playback_ports[k]);-    }-    jack_free(playback_ports);-  }-}--template <typename Link>-void AudioPlatform<Link>::stop()-{-  jack_deactivate(mpJackClient);-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_Portaudio.hpp view
@@ -21,6 +21,7 @@  #include "AudioEngine.hpp" #include <ableton/link/HostTimeFilter.hpp>+#include <ableton/platforms/Config.hpp> #include <portaudio.h>  namespace ableton@@ -28,34 +29,31 @@ namespace linkaudio { -template <typename Link> class AudioPlatform { public:   AudioPlatform(Link& link);   ~AudioPlatform(); -  AudioEngine<Link> mEngine;+  AudioEngine mEngine;  private:   static int audioCallback(const void* inputBuffer,-                           void* outputBuffer,-                           unsigned long inNumFrames,-                           const PaStreamCallbackTimeInfo* timeInfo,-                           PaStreamCallbackFlags statusFlags,-                           void* userData);+    void* outputBuffer,+    unsigned long inNumFrames,+    const PaStreamCallbackTimeInfo* timeInfo,+    PaStreamCallbackFlags statusFlags,+    void* userData);    void initialize();   void uninitialize();   void start();   void stop(); -  link::HostTimeFilter<typename Link::Clock> mHostTimeFilter;+  link::HostTimeFilter<link::platform::Clock> mHostTimeFilter;   double mSampleTime;   PaStream* pStream; };  } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_Portaudio.ipp"
− link/examples/linkaudio/AudioPlatform_Portaudio.ipp
@@ -1,168 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#include <chrono>-#include <iostream>--namespace ableton-{-namespace linkaudio-{--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)-  : mEngine(link)-  , mSampleTime(0.)-{-  mEngine.setSampleRate(44100.);-  mEngine.setNumFrames(512);-  initialize();-  start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform()-{-  stop();-  uninitialize();-}--template <typename Link>-int AudioPlatform<Link>::audioCallback(const void* /*inputBuffer*/,-                                       void* outputBuffer,-                                       unsigned long inNumFrames,-                                       const PaStreamCallbackTimeInfo* /*timeInfo*/,-                                       PaStreamCallbackFlags /*statusFlags*/,-                                       void* userData)-{-  using namespace std::chrono;-  float* buffer = static_cast<float*>(outputBuffer);-  AudioPlatform& platform = *static_cast<AudioPlatform*>(userData);-  AudioEngine<Link>& engine = platform.mEngine;--  const auto hostTime =-    platform.mHostTimeFilter.sampleTimeToHostTime(platform.mSampleTime);--  platform.mSampleTime += static_cast<double>(inNumFrames);--  const auto bufferBeginAtOutput = hostTime + engine.mOutputLatency.load();--  engine.audioCallback(bufferBeginAtOutput, inNumFrames);--  for (unsigned long i = 0; i < inNumFrames; ++i)-  {-    buffer[i * 2] = static_cast<float>(engine.mBuffers[0][i]);-    buffer[i * 2 + 1] = static_cast<float>(engine.mBuffers[1][i]);-  }--  return paContinue;-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{-  PaError result = Pa_Initialize();-  if (result)-  {-    std::cerr << "Could not initialize Audio Engine. " << result << std::endl;-    std::terminate();-  }--  PaStreamParameters outputParameters;-  outputParameters.device = Pa_GetDefaultOutputDevice();-  if (outputParameters.device == paNoDevice)-  {-    std::cerr << "Could not get Audio Device. " << std::endl;-    std::terminate();-  }--  outputParameters.channelCount = 2;-  outputParameters.sampleFormat = paFloat32;-  outputParameters.suggestedLatency =-    Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;-  outputParameters.hostApiSpecificStreamInfo = nullptr;-  mEngine.mOutputLatency.store(-    std::chrono::microseconds(llround(outputParameters.suggestedLatency * 1.0e6)));-  result = Pa_OpenStream(&pStream,-                         nullptr,-                         &outputParameters,-                         mEngine.mSampleRate,-                         mEngine.mBuffers[0].size(),-                         paClipOff,-                         &audioCallback,-                         this);--  if (result)-  {-    std::cerr << "Could not open stream. " << result << std::endl;-    std::terminate();-  }--  if (!pStream)-  {-    std::cerr << "No valid audio stream." << std::endl;-    std::terminate();-  }-}--template <typename Link>-void AudioPlatform<Link>::uninitialize()-{-  PaError result = Pa_CloseStream(pStream);-  if (result)-  {-    std::cerr << "Could not close Audio Stream. " << result << std::endl;-  }-  Pa_Terminate();--  if (!pStream)-  {-    std::cerr << "No valid audio stream." << std::endl;-    std::terminate();-  }-}--template <typename Link>-void AudioPlatform<Link>::start()-{-  PaError result = Pa_StartStream(pStream);-  if (result)-  {-    std::cerr << "Could not start Audio Stream. " << result << std::endl;-  }-}--template <typename Link>-void AudioPlatform<Link>::stop()-{-  if (pStream == nullptr)-  {-    return;-  }--  PaError result = Pa_StopStream(pStream);-  if (result)-  {-    std::cerr << "Could not stop Audio Stream. " << result << std::endl;-    std::terminate();-  }-}--} // namespace linkaudio-} // namespace ableton
link/examples/linkaudio/AudioPlatform_Wasapi.hpp view
@@ -38,10 +38,8 @@ // and then terminate the application. void fatalError(HRESULT result, LPCTSTR context); -template <typename Link> DWORD renderAudioRunloop(LPVOID); -template <typename Link> class AudioPlatform { public:@@ -50,7 +48,7 @@    DWORD audioRunloop(); -  AudioEngine<Link> mEngine;+  AudioEngine mEngine;  private:   UINT32 bufferSize();@@ -58,7 +56,7 @@   void initialize();   void start(); -  link::HostTimeFilter<typename Link::Clock> mHostTimeFilter;+  link::HostTimeFilter<platforms::windows::Clock> mHostTimeFilter;   double mSampleTime;    IMMDevice* mDevice;@@ -72,5 +70,3 @@  } // namespace linkaudio } // namespace ableton--#include "AudioPlatform_Wasapi.ipp"
− link/examples/linkaudio/AudioPlatform_Wasapi.ipp
@@ -1,344 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#include <Comdef.h>-#include <chrono>--// WARNING: This file provides an audio driver for Windows using WASAPI. This driver is-// considered experimental and has problems with low-latency playback. Please consider-// using the ASIO driver instead.--namespace ableton-{-namespace linkaudio-{--// GUID identifiers used to when looking up COM enumerators and devices-static const IID kMMDeviceEnumeratorId = __uuidof(MMDeviceEnumerator);-static const IID kIMMDeviceEnumeratorId = __uuidof(IMMDeviceEnumerator);-static const IID kAudioClientId = __uuidof(IAudioClient);-static const IID kAudioRenderClientId = __uuidof(IAudioRenderClient);--// Controls how large the driver's ring buffer will be, expressed in terms of-// 100-nanosecond units. This value also influences the overall driver latency.-static const REFERENCE_TIME kBufferDuration = 1000000;--// How long to block the runloop while waiting for an event callback.-static const DWORD kWaitTimeoutInMs = 2000;--void fatalError(HRESULT result, LPCTSTR context)-{-  if (result > 0)-  {-    _com_error error(result);-    LPCTSTR errorMessage = error.ErrorMessage();-    std::cerr << context << ": " << errorMessage << std::endl;-  }-  else-  {-    std::cerr << context << std::endl;-  }--  std::terminate();-}--template <typename Link>-DWORD renderAudioRunloop(LPVOID lpParam)-{-  AudioPlatform<Link>* platform = static_cast<AudioPlatform<Link>*>(lpParam);-  return platform->audioRunloop();-}--template <typename Link>-AudioPlatform<Link>::AudioPlatform(Link& link)-  : mEngine(link)-  , mSampleTime(0)-  , mDevice(nullptr)-  , mAudioClient(nullptr)-  , mRenderClient(nullptr)-  , mStreamFormat(nullptr)-  , mEventHandle(nullptr)-  , mAudioThreadHandle(nullptr)-  , mIsRunning(false)-{-  initialize();-  mEngine.setNumFrames(bufferSize());-  mEngine.setSampleRate(mStreamFormat->nSamplesPerSec);-  start();-}--template <typename Link>-AudioPlatform<Link>::~AudioPlatform()-{-  // WARNING: Here be dragons!-  // The WASAPI driver is not thread-safe, and crashes may occur when shutting down due-  // to these fields being concurrently accessed in the audio thread. Introducing a mutex-  // in the audio thread is not an appropriate solution to fix this race condition; a more-  // robust solution needs to be considered instead.--  if (mDevice != nullptr)-  {-    mDevice->Release();-  }-  if (mAudioClient != nullptr)-  {-    mAudioClient->Release();-  }-  if (mRenderClient != nullptr)-  {-    mRenderClient->Release();-  }-  CoTaskMemFree(mStreamFormat);-}--template <typename Link>-UINT32 AudioPlatform<Link>::bufferSize()-{-  UINT32 bufferSize;-  HRESULT result = mAudioClient->GetBufferSize(&bufferSize);-  if (FAILED(result))-  {-    fatalError(result, "Could not get buffer size");-    return 0; // not reached-  }--  return bufferSize;-}--template <typename Link>-void AudioPlatform<Link>::initialize()-{-  HRESULT result = CoInitialize(nullptr);-  if (FAILED(result))-  {-    fatalError(result, "Could not initialize COM library");-  }--  IMMDeviceEnumerator* enumerator = nullptr;-  result = CoCreateInstance(kMMDeviceEnumeratorId,-                            nullptr,-                            CLSCTX_ALL,-                            kIMMDeviceEnumeratorId,-                            (void**)&enumerator);-  if (FAILED(result))-  {-    fatalError(result, "Could not create device instance");-  }--  result = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &(mDevice));-  if (FAILED(result))-  {-    fatalError(result, "Could not get default audio endpoint");-  }-  else-  {-    enumerator->Release();-    enumerator = nullptr;-  }--  result =-    mDevice->Activate(kAudioClientId, CLSCTX_ALL, nullptr, (void**)&(mAudioClient));-  if (FAILED(result))-  {-    fatalError(result, "Could not activate audio device");-  }--  result = mAudioClient->GetMixFormat(&(mStreamFormat));-  if (FAILED(result))-  {-    fatalError(result, "Could not get mix format");-  }--  if (mStreamFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE)-  {-    WAVEFORMATEXTENSIBLE* streamFormatEx =-      reinterpret_cast<WAVEFORMATEXTENSIBLE*>(mStreamFormat);-    if (streamFormatEx->SubFormat != KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)-    {-      fatalError(0, "Sorry, only IEEE floating point streams are supported");-    }-  }-  else-  {-    fatalError(0, "Sorry, only extensible wave streams are supported");-  }--  result = mAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,-                                    AUDCLNT_STREAMFLAGS_EVENTCALLBACK,-                                    kBufferDuration,-                                    0,-                                    mStreamFormat,-                                    nullptr);-  if (FAILED(result))-  {-    fatalError(result, "Could not initialize audio device");-  }--  mEventHandle = CreateEvent(nullptr, false, false, nullptr);-  if (mEventHandle == nullptr)-  {-    fatalError(result, "Could not create event handle");-  }--  result = mAudioClient->GetService(kAudioRenderClientId, (void**)&(mRenderClient));-  if (FAILED(result))-  {-    fatalError(result, "Could not get audio render service");-  }--  mIsRunning = true;-  LPTHREAD_START_ROUTINE threadEntryPoint =-    reinterpret_cast<LPTHREAD_START_ROUTINE>(renderAudioRunloop<Link>);-  mAudioThreadHandle = CreateThread(nullptr, 0, threadEntryPoint, this, 0, nullptr);-  if (mAudioThreadHandle == nullptr)-  {-    fatalError(GetLastError(), "Could not create audio thread");-  }-}--template <typename Link>-void AudioPlatform<Link>::start()-{-  UINT32 bufSize = bufferSize();-  BYTE* buffer;-  HRESULT result = mRenderClient->GetBuffer(bufSize, &buffer);-  if (FAILED(result))-  {-    fatalError(result, "Could not get render client buffer (in start audio engine)");-  }--  result = mRenderClient->ReleaseBuffer(bufSize, 0);-  if (FAILED(result))-  {-    fatalError(result, "Could not release buffer");-  }--  result = mAudioClient->SetEventHandle(mEventHandle);-  if (FAILED(result))-  {-    fatalError(result, "Could not set event handle to audio client");-  }--  REFERENCE_TIME latency;-  result = mAudioClient->GetStreamLatency(&latency);-  if (FAILED(result))-  {-    fatalError(result, "Could not get stream latency");-  }--  result = mAudioClient->Start();-  if (FAILED(result))-  {-    fatalError(result, "Could not start audio client");-  }-}--template <typename Link>-DWORD AudioPlatform<Link>::audioRunloop()-{-  while (mIsRunning)-  {-    DWORD wait = WaitForSingleObject(mEventHandle, kWaitTimeoutInMs);-    if (wait != WAIT_OBJECT_0)-    {-      mIsRunning = false;-      mAudioClient->Stop();-      return wait;-    }--    // Get the amount of padding, which basically is the amount of data in the driver's-    // ring buffer that is filled with unread data. Thus, subtracting this amount from-    // the buffer size gives the effective buffer size, which is the amount of frames-    // that can be safely written to the driver.-    UINT32 paddingFrames;-    HRESULT result = mAudioClient->GetCurrentPadding(&paddingFrames);-    if (FAILED(result))-    {-      fatalError(result, "Could not get number of padding frames");-    }--    const UINT32 numSamples = bufferSize() - paddingFrames;--    BYTE* buffer;-    result = mRenderClient->GetBuffer(numSamples, &buffer);-    if (FAILED(result))-    {-      fatalError(result, "Could not get render client buffer (in callback)");-    }--    const double sampleRate = static_cast<double>(mStreamFormat->nSamplesPerSec);-    using namespace std::chrono;-    const auto bufferDuration =-      duration_cast<microseconds>(duration<double>{numSamples / sampleRate});--    const auto hostTime = mHostTimeFilter.sampleTimeToHostTime(mSampleTime);--    mSampleTime += numSamples;--    const auto bufferBeginAtOutput = hostTime + mEngine.mOutputLatency.load();--    mEngine.audioCallback(bufferBeginAtOutput, numSamples);--    float* floatBuffer = reinterpret_cast<float*>(buffer);-    for (WORD i = 0; i < numSamples; ++i)-    {-      if (i >= mEngine.mBuffers[0].size())-      {-        break;-      }-      for (WORD j = 0; j < mStreamFormat->nChannels; ++j)-      {-        floatBuffer[j + (i * mStreamFormat->nChannels)] =-          static_cast<float>(mEngine.mBuffers[j][i]);-      }-    }--    // Write the buffer to the audio driver and subsequently free the buffer memory-    result = mRenderClient->ReleaseBuffer(numSamples, 0);-    if (FAILED(result))-    {-      fatalError(result, "Error rendering data");-    }-  } // end of runloop--  mIsRunning = false;-  return 0;-}---// void fillBuffer(MetronomeSynth& metronome,-//  const UINT32 startFrame,-//  const UINT32 numSamples,-//  const UINT32 numChannels,-//  BYTE* buffer)-//{-//  float* floatBuffer = reinterpret_cast<float*>(buffer);-//  UINT32 frame = startFrame;-//  while (frame < numSamples * numChannels)-//  {-//    const float sample = static_cast<float>(metronome.getSample());-//    for (UINT32 channel = 0; channel < numChannels; ++channel)-//    {-//      floatBuffer[frame++] = sample;-//    }-//  }-//}--} // namespace linkaudio-} // namespace ableton
− link/examples/linkaudio/LinkAudioRenderer.hpp
@@ -1,418 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#if defined(LINK_AUDIO)--#include <ableton/LinkAudio.hpp>-#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Queue.hpp>-#include <ableton/util/FloatIntConversion.hpp>--namespace ableton-{-namespace linkaudio-{--namespace-{--template <typename T>-T cubicInterpolate(const std::array<T, 4>& p, double t)-{-  double a = -0.5 * static_cast<double>(p[0]) + 1.5 * static_cast<double>(p[1])-             - 1.5 * static_cast<double>(p[2]) + 0.5 * static_cast<double>(p[3]);-  double b = static_cast<double>(p[0]) - 2.5 * static_cast<double>(p[1])-             + 2.0 * static_cast<double>(p[2]) - 0.5 * static_cast<double>(p[3]);-  double c = -0.5 * static_cast<double>(p[0]) + 0.5 * static_cast<double>(p[2]);-  auto d = static_cast<double>(p[1]);-  return static_cast<T>(a * t * t * t + b * t * t + c * t + d);-}--template <typename T>-T linearInterpolate(T value, T inMin, T inMax, T outMin, T outMax)-{-  return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;-}--} // namespace--template <typename Link>-class LinkAudioRenderer-{-  struct Buffer-  {-    std::array<double, 512> mSamples; // Should at least hold max network buffer size-    LinkAudioSource::BufferHandle::Info mInfo;-  };-  using Queue = link_audio::Queue<Buffer>;--public:-  LinkAudioRenderer(Link& link, double& sampleRate)-    : mLink(link)-    , mSink(mLink, "A Sink", 4096)-    , mSampleRate(sampleRate)-  {-    auto queue = Queue(2048, {});-    mpQueueWriter = std::make_shared<typename Queue::Writer>(std::move(queue.writer()));-    mpQueueReader = std::make_shared<typename Queue::Reader>(std::move(queue.reader()));-  }--  ~LinkAudioRenderer() { mpSource.reset(); }--  void send(double* pSamples,-            size_t numFrames,-            typename Link::SessionState sessionState,-            double sampleRate,-            const std::chrono::microseconds hostTime,-            double quantum)-  {-    // We can only send audio if the sink can provide a buffer to write to-    auto buffer = LinkAudioSink::BufferHandle(mSink);-    if (buffer)-    {-      // The sink expects 16 bit integers so the doubles have to be converted-      for (auto i = 0u; i < numFrames; ++i)-      {-        buffer.samples[i] = ableton::util::floatToInt16(pSamples[i]);-      }--      // The buffer is commited to Link Audio with the required timing information-      const auto beatsAtBufferBegin = sessionState.beatAtTime(hostTime, quantum);-      buffer.commit(sessionState,-                    beatsAtBufferBegin,-                    quantum,-                    static_cast<uint32_t>(numFrames),-                    1, // mono-                    static_cast<uint32_t>(sampleRate));-    }-  }--  void receive(double* pRightSamples,-               size_t numFrames,-               typename Link::SessionState sessionState,-               double sampleRate,-               const std::chrono::microseconds hostTime,-               double quantum)-  {-    // Get all slots from the queue-    while (mpQueueReader->retainSlot())-    {-    }--    // Calculate the beat range we want to render to the output buffer-    constexpr auto kLatencyInBeats = 4;-    const auto targetBeatsAtBufferBegin =-      sessionState.beatAtTime(hostTime, quantum) - kLatencyInBeats;-    const auto targetBeatsAtBufferEnd =-      sessionState.beatAtTime(-        hostTime-          + std::chrono::duration_cast<std::chrono::microseconds>(-            std::chrono::duration<double>((double(numFrames)) / sampleRate)),-        quantum)-      - kLatencyInBeats;--    // Drop slots that are too old while we are not rendering-    while (!moStartReadPos && mpQueueReader->numRetainedSlots() > 0)-    {-      if ((*mpQueueReader)[0]->mInfo.endBeats(sessionState, quantum)-          < targetBeatsAtBufferBegin)-      {-        mpQueueReader->releaseSlot();-      }-      else-      {-        break;-      }-    }--    // Return early if there is no audio buffer to read from-    if (mpQueueReader->numRetainedSlots() == 0)-    {-      moLastFrameIdx = std::nullopt;-      moStartReadPos = std::nullopt;-      mBuffered = 0;-      return;-    }--    // Return early if the next buffer is too new and we are not rendering-    if (!moStartReadPos-        && (*mpQueueReader)[0]->mInfo.beginBeats(sessionState, quantum)-             > targetBeatsAtBufferBegin)-    {-      moLastFrameIdx = std::nullopt;-      moStartReadPos = std::nullopt;-      mBuffered = 0;-      return;-    }--    // Initialize start read position if not set-    if (!moStartReadPos)-    {-      const auto& info = (*mpQueueReader)[0]->mInfo;-      const auto startBufferBegin = *info.beginBeats(sessionState, quantum);-      const auto startBufferEnd = *info.endBeats(sessionState, quantum);--      // Calculate initial position from target beat-      moStartReadPos = linearInterpolate(targetBeatsAtBufferBegin,-                                         startBufferBegin,-                                         startBufferEnd,-                                         0.0,-                                         double(info.numFrames));-    }--    const auto startFramePos = *moStartReadPos;--    // Loop through queue to find end beat and collect total frames-    auto totalFrames = 0.0;-    auto foundEnd = false;--    for (auto i = 0u; i < mpQueueReader->numRetainedSlots(); ++i)-    {-      const auto& info = (*mpQueueReader)[i]->mInfo;-      const auto bufferBegin = *info.beginBeats(sessionState, quantum);-      const auto bufferEnd = *info.endBeats(sessionState, quantum);--      if (targetBeatsAtBufferEnd >= bufferBegin && targetBeatsAtBufferEnd < bufferEnd)-      {-        const auto targetBeatsFrame = linearInterpolate(-          targetBeatsAtBufferEnd, bufferBegin, bufferEnd, 0.0, double(info.numFrames));--        totalFrames += targetBeatsFrame;-        foundEnd = true;-        break;-      }-      else-      {-        totalFrames += double(info.numFrames);-      }-    }--    // We don't have enough frames buffered-    if (!foundEnd)-    {-      moLastFrameIdx = std::nullopt;-      moStartReadPos = std::nullopt;-      mBuffered = 0;-      return;-    }--    // Take the frames we have already rendered into account-    totalFrames -= startFramePos;--    // Beat time jump, we can't continue rendering-    if (totalFrames <= 0.0)-    {-      moLastFrameIdx = std::nullopt;-      moStartReadPos = std::nullopt;-      mBuffered = 0;-      return;-    }--    // The increment is how many source frames to advance per output frame-    // This automatically handles both tempo changes and sample rate differences by-    // re-pitching the audio-    const auto frameIncrement = totalFrames / double(numFrames);-    auto readPos = startFramePos;--    // Helper to get sample at index, handling buffer boundaries-    auto getSample = [&](size_t idx) -> double-    {-      size_t bufferIdx = 0;-      size_t currentIdx = idx;--      while (bufferIdx < mpQueueReader->numRetainedSlots())-      {-        auto& currentBuffer = *((*mpQueueReader)[bufferIdx]);-        if (currentIdx < currentBuffer.mInfo.numFrames)-        {-          return currentBuffer.mSamples[currentIdx];-        }-        currentIdx -= currentBuffer.mInfo.numFrames;-        ++bufferIdx;-      }--      return 0.0;-    };--    for (auto frame = 0u; frame < numFrames; ++frame)-    {-      const auto framePos = readPos + frame * frameIncrement;-      const auto frameIdx = static_cast<size_t>(std::floor(framePos));-      const auto t = framePos - std::floor(framePos);--      // Update the interpolator cache-      while (!moLastFrameIdx || (moLastFrameIdx && frameIdx > *moLastFrameIdx))-      {-        mReceiverSampleCache[3] = mReceiverSampleCache[2];-        mReceiverSampleCache[2] = mReceiverSampleCache[1];-        mReceiverSampleCache[1] = mReceiverSampleCache[0];-        mReceiverSampleCache[0] = (frameIdx > 0) ? getSample(frameIdx - 1) : getSample(0);-        moLastFrameIdx = moLastFrameIdx ? (*moLastFrameIdx + 1) : frameIdx;-      }--      // Write the output frame-      pRightSamples[frame] = cubicInterpolate(mReceiverSampleCache, t);--      // Drop buffer if we've moved past it-      const auto& currentInfo = (*mpQueueReader)[0]->mInfo;-      if (frameIdx >= currentInfo.numFrames)-      {-        readPos -= double(currentInfo.numFrames);-        moLastFrameIdx = frameIdx - currentInfo.numFrames;-        mpQueueReader->releaseSlot();-      }-    }--    // Update the read position for the next buffer-    *moStartReadPos = readPos + double(numFrames) * frameIncrement;--    // Calculate buffered time-    auto buffered =-      -static_cast<float>(*moStartReadPos) / float((*mpQueueReader)[0]->mInfo.sampleRate);-    if (mpQueueReader->numRetainedSlots() > 0)-    {-      for (auto i = 1u; i < mpQueueReader->numRetainedSlots(); ++i)-      {-        const auto& info = (*mpQueueReader)[i]->mInfo;-        buffered += float(info.numFrames) / float(info.sampleRate);-      }-    }-    mBuffered = buffered;-  }--  void operator()(double* pLeftSamples,-                  double* pRightSamples,-                  size_t numFrames,-                  typename Link::SessionState sessionState,-                  double sampleRate,-                  const std::chrono::microseconds hostTime,-                  double quantum)-  {-    // Send the left channel to Link-    send(pLeftSamples, numFrames, sessionState, sampleRate, hostTime, quantum);--    // Write the received audio to the right channel-    receive(pRightSamples, numFrames, sessionState, sampleRate, hostTime, quantum);-  }---  bool hasSource() const { return mpSource != nullptr; }--  void removeSource()-  {-    if (mpSource)-    {-      mpSource.reset();--      while (mpQueueReader->retainSlot())-      {-      }--      while (mpQueueReader->numRetainedSlots() > 0)-      {-        mpQueueReader->releaseSlot();-      }--      moLastFrameIdx = std::nullopt;-      moStartReadPos = std::nullopt;-    }-  }--  float buffered() const { return mBuffered; }--  void createSource(const ChannelId& channelId)-  {-    mpSource = std::make_unique<LinkAudioSource>(-      mLink,-      channelId,-      [this](ableton::LinkAudioSource::BufferHandle bufferHandle)-      { onSourceBuffer(bufferHandle); });-  }--  void onSourceBuffer(const LinkAudioSource::BufferHandle bufferHandle)-  {-    // When we receive a buffer from Link, we prime it for the audio rendering callback.-    // This runs on the main Link thread, so we should not block it for too long.-    if (mpQueueWriter->retainSlot())-    {-      auto& buffer = *((*mpQueueWriter)[0]);-      buffer.mInfo = bufferHandle.info;-      buffer.mInfo.numChannels = 1;--      for (auto i = 0u; i < bufferHandle.info.numFrames; ++i)-      {-        buffer.mSamples[i] = util::int16ToFloat<double>(-          bufferHandle.samples[i * bufferHandle.info.numChannels]);-      }--      mpQueueWriter->releaseSlot();-    }-  }--  Link& mLink;-  LinkAudioSink mSink;-  std::unique_ptr<LinkAudioSource> mpSource;-  double& mSampleRate;--  std::optional<double> moStartReadPos;-  std::atomic<float> mBuffered = 0;--private:-  std::shared_ptr<typename Queue::Writer> mpQueueWriter;-  std::shared_ptr<typename Queue::Reader> mpQueueReader;--  std::array<double, 4> mReceiverSampleCache = {{0.0, 0.0, 0.0, 0.0}};-  std::optional<size_t> moLastFrameIdx = std::nullopt;-};--} // namespace linkaudio-} // namespace ableton--#else--namespace ableton-{-namespace linkaudio-{--template <typename Link>-class LinkAudioRenderer-{-public:-  LinkAudioRenderer(Link&, double&) {}--  // In case we don't support LinkAudio we just copy the left output buffer to the right-  void operator()(double* pLeftSamples,-                  double* pRightSamples,-                  size_t numFrames,-                  typename Link::SessionState,-                  double,-                  const std::chrono::microseconds,-                  double)-  {-    std::copy_n(pLeftSamples, numFrames, pRightSamples);-  }-};--} // namespace linkaudio-} // namespace ableton--#endif
link/extensions/abl_link/include/abl_link.h view
@@ -18,7 +18,6 @@  */  #include <stdbool.h>-#include <stddef.h> #include <stdint.h>  #ifdef __cplusplus@@ -62,52 +61,52 @@    */    /*! @brief The representation of an abl_link instance*/-  struct abl_link+  typedef struct abl_link   {     void *impl;-  };+  } abl_link;    /*! @brief Construct a new abl_link instance with an initial tempo.    *  Thread-safe: yes    *  Realtime-safe: no    */-  struct abl_link abl_link_create(double bpm);+  abl_link abl_link_create(double bpm);    /*! @brief Delete an abl_link instance.    *  Thread-safe: yes    *  Realtime-safe: no    */-  void abl_link_destroy(struct abl_link link);+  void abl_link_destroy(abl_link link);    /*! @brief Is Link currently enabled?    *  Thread-safe: yes    *  Realtime-safe: yes    */-  bool abl_link_is_enabled(struct abl_link link);+  bool abl_link_is_enabled(abl_link link);    /*! @brief Enable/disable Link.    *  Thread-safe: yes    *  Realtime-safe: no    */-  void abl_link_enable(struct abl_link link, bool enable);+  void abl_link_enable(abl_link link, bool enable);    /*! @brief: Is start/stop synchronization enabled?    *  Thread-safe: yes-   *  Realtime-safe: yes+   *  Realtime-safe: no    */-  bool abl_link_is_start_stop_sync_enabled(struct abl_link link);+  bool abl_link_is_start_stop_sync_enabled(abl_link link);    /*! @brief: Enable start/stop synchronization.    *  Thread-safe: yes-   *  Realtime-safe: yes+   *  Realtime-safe: no    */-  void abl_link_enable_start_stop_sync(struct abl_link link, bool enabled);+  void abl_link_enable_start_stop_sync(abl_link link, bool enabled);    /*! @brief How many peers are currently connected in a Link session?    *  Thread-safe: yes    *  Realtime-safe: yes    */-  uint64_t abl_link_num_peers(struct abl_link link);+  uint64_t abl_link_num_peers(abl_link link);    /*! @brief Register a callback to be notified when the number of    *  peers in the Link session changes.@@ -116,9 +115,9 @@    *    *  @discussion The callback is invoked on a Link-managed thread.    */-  void abl_link_set_num_peers_callback(struct abl_link link,-    void (*callback)(uint64_t num_peers, void *context),-    void *context);+  typedef void (*abl_link_num_peers_callback)(uint64_t num_peers, void *context);+  void abl_link_set_num_peers_callback(+    abl_link link, abl_link_num_peers_callback callback, void *context);    /*! @brief Register a callback to be notified when the session    *  tempo changes.@@ -127,8 +126,9 @@    *    *  @discussion The callback is invoked on a Link-managed thread.    */+  typedef void (*abl_link_tempo_callback)(double tempo, void *context);   void abl_link_set_tempo_callback(-    struct abl_link link, void (*callback)(double tempo, void *context), void *context);+    abl_link link, abl_link_tempo_callback callback, void *context);    /*! brief: Register a callback to be notified when the state of    *  start/stop isPlaying changes.@@ -137,15 +137,15 @@    *    *  @discussion The callback is invoked on a Link-managed thread.    */-  void abl_link_set_start_stop_callback(struct abl_link link,-    void (*callback)(bool is_playing, void *context),-    void *context);+  typedef void (*abl_link_start_stop_callback)(bool is_playing, void *context);+  void abl_link_set_start_stop_callback(+    abl_link link, abl_link_start_stop_callback callback, void *context);    /*! brief: Get the current link clock time in microseconds.    *  Thread-safe: yes    *  Realtime-safe: yes    */-  int64_t abl_link_clock_micros(struct abl_link link);+  int64_t abl_link_clock_micros(abl_link link);    /*! @brief The representation of the current local state of a client in a Link Session    *@@ -163,7 +163,7 @@    *  joining or leaving a Link session. After joining a Link session    *  start/stop change requests will be communicated to all connected peers.    */-  typedef struct abl_link_session_state // NOLINT(modernize-use-using)+  typedef struct abl_link_session_state   {     void *impl;   } abl_link_session_state;@@ -194,7 +194,7 @@    *  session_state should not be created on the audio thread.    */   void abl_link_capture_audio_session_state(-    struct abl_link link, abl_link_session_state session_state);+    abl_link link, abl_link_session_state session_state);    /*! @brief Commit the given Session State to the Link session from the    *  audio thread.@@ -206,11 +206,11 @@    *  communicated to other peers in the session.    */   void abl_link_commit_audio_session_state(-    struct abl_link link, abl_link_session_state session_state);+    abl_link link, abl_link_session_state session_state);    /*! @brief Capture the current Link Session State from an application thread.-   *  Thread-safe: yes-   *  Realtime-safe: no+   *  Thread-safe: no+   *  Realtime-safe: yes    *    *  @discussion Provides a mechanism for capturing the Link Session State from an    *  application thread (other than the audio thread). After capturing the session_state@@ -218,7 +218,7 @@    *  scope.    */   void abl_link_capture_app_session_state(-    struct abl_link link, abl_link_session_state session_state);+    abl_link link, abl_link_session_state session_state);    /*! @brief Commit the given Session State to the Link session from an    *  application thread.@@ -230,7 +230,7 @@    *  session.    */   void abl_link_commit_app_session_state(-    struct abl_link link, abl_link_session_state session_state);+    abl_link link, abl_link_session_state session_state);    /*! @brief: The tempo of the timeline, in Beats Per Minute.    *@@ -317,19 +317,19 @@    *  join.    */   void abl_link_force_beat_at_time(-    abl_link_session_state session_state, double beat, int64_t time, double quantum);+    abl_link_session_state session_state, double beat, uint64_t time, double quantum);    /*! @brief: Set if transport should be playing or stopped, taking effect at the given    *  time.    */   void abl_link_set_is_playing(-    abl_link_session_state session_state, bool is_playing, int64_t time);+    abl_link_session_state session_state, bool is_playing, uint64_t time);    /*! @brief: Is transport playing? */   bool abl_link_is_playing(abl_link_session_state session_state);    /*! @brief: Get the time at which a transport start/stop occurs */-  int64_t abl_link_time_for_is_playing(abl_link_session_state session_state);+  uint64_t abl_link_time_for_is_playing(abl_link_session_state session_state);    /*! @brief: Convenience function to attempt to map the given beat to the time    *  when transport is starting to play in context of the given quantum.@@ -343,254 +343,9 @@   void abl_link_set_is_playing_and_request_beat_at_time(     abl_link_session_state session_state,     bool is_playing,-    int64_t time,+    uint64_t time,     double beat,     double quantum);--  /*! @brief Is Link Audio enabled-   *  Thread-safe: yes-   *  Realtime-safe: yes-   */-  bool abl_link_audio_is_link_audio_enabled(struct abl_link link);--  /*! @brief Enable or disable audio.-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  void abl_link_audio_enable_link_audio(struct abl_link link, bool enabled);--  /*! @brief Get the local peer name for identification in the Link session.-   *-   *  @discussion Writes the peer name into @p buffer as a null-terminated string,-   *  truncating if necessary. Returns the number of bytes required to store the full-   *  name, excluding the null terminator — identical to the snprintf convention.-   *  If the return value is >= @p buffer_size, the output was truncated.-   *  Passing NULL or 0 for @p buffer / @p buffer_size returns the required size-   *  without writing anything.-   *-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  size_t abl_link_audio_peer_name(struct abl_link link, char *buffer, size_t buffer_size);--  /*! @brief Change the local peer name for identification in the Link session.-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  void abl_link_audio_set_peer_name(struct abl_link link, const char *name);--  /*! @brief Identifier for Link Audio channels/peers/sessions. */-  struct abl_link_audio_channel_id-  {-    uint8_t bytes[8];-  };--  struct abl_link_audio_peer_id-  {-    uint8_t bytes[8];-  };--  struct abl_link_audio_session_id-  {-    uint8_t bytes[8];-  };--  /*! @brief A Link Audio channel description.-   *-   *  @discussion The id and peer_id are persistent for the lifetime of a channel.-   *  The name and peer_name may change over time and are meant for display purposes.-   */-  struct abl_link_audio_channel-  {-    struct abl_link_audio_channel_id id;-    const char *name;-    struct abl_link_audio_peer_id peer_id;-    const char *peer_name;-  };--  /*! @brief A list of Link Audio channels. */-  struct abl_link_audio_channel_list-  {-    struct abl_link_audio_channel *channels;-    size_t count;-  };--  /*! @brief Get the list of available Link Audio channels.-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  struct abl_link_audio_channel_list abl_link_audio_get_channels(struct abl_link link);--  /*! @brief Free a channel list returned by abl_link_audio_get_channels. */-  void abl_link_audio_free_channel_list(struct abl_link_audio_channel_list list);--  /*! @brief Register a callback to be notified when the set of available-   *  audio channels changes. This will be called when channels are discovered or-   *  disappear and when names change.-   *  Thread-safe: yes-   *  Realtime-safe: no-   *-   *  @discussion The callback is invoked on a Link-managed thread.-   */-  void abl_link_audio_set_channels_changed_callback(-    struct abl_link link, void (*callback)(void *context), void *context);--  /*! @brief The representation of an abl_link_audio_sink instance */-  struct abl_link_audio_sink-  {-    void *impl;-  };--  /*! @brief Construct a Link Audio sink to announce an audio channel. */-  struct abl_link_audio_sink abl_link_audio_sink_create(-    struct abl_link link, const char *name, size_t max_num_samples);--  /*! @brief Destroy a Link Audio sink. */-  void abl_link_audio_sink_destroy(struct abl_link_audio_sink sink);--  /*! @brief Get the name of a Link Audio sink.-   *-   *  @discussion Writes the sink name into @p buffer as a null-terminated string,-   *  truncating if necessary. Returns the number of bytes required to store the full-   *  name, excluding the null terminator — identical to the snprintf convention.-   *  If the return value is >= @p buffer_size, the output was truncated.-   *  Passing NULL or 0 for @p buffer / @p buffer_size returns the required size-   *  without writing anything.-   *-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  size_t abl_link_audio_sink_name(-    struct abl_link_audio_sink sink, char *buffer, size_t buffer_size);--  /*! @brief Set the name of a Link Audio sink.-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  void abl_link_audio_sink_set_name(struct abl_link_audio_sink sink, const char *name);--  /*! @brief Request a maximum buffer size for future buffers.-   *  Thread-safe: yes-   *  Realtime-safe: yes-   */-  void abl_link_audio_sink_request_max_num_samples(-    struct abl_link_audio_sink sink, size_t num_samples);--  /*! @brief Get the current maximum number of samples a buffer handle can hold.-   *  Thread-safe: yes-   *  Realtime-safe: yes-   */-  size_t abl_link_audio_sink_max_num_samples(struct abl_link_audio_sink sink);--  /*! @brief Handle to a buffer for writing audio samples. */-  struct abl_link_audio_sink_buffer_handle-  {-    void *impl;-    int16_t *samples;-    size_t max_num_samples;-  };--  /*! @brief Retain a buffer for writing audio samples. Only one buffer can be retained-   *  at a time. The handle must not outlive the sink it was created from.-   *  Thread-safe: no-   *  Realtime-safe: yes-   */-  struct abl_link_audio_sink_buffer_handle abl_link_audio_sink_retain_buffer(-    struct abl_link_audio_sink sink);--  /*! @brief Check if a buffer handle is valid.-   *  Thread-safe: no-   *  Realtime-safe: yes-   */-  bool abl_link_audio_sink_buffer_is_valid(-    const struct abl_link_audio_sink_buffer_handle *handle);--  /*! @brief Commit a buffer after writing samples. The handle is invalid after this.-   *  num_frames * num_channels must not exceed max_num_samples. The session state,-   *  quantum, and beats_at_buffer_begin must match those used for rendering.-   *  Thread-safe: no-   *  Realtime-safe: yes-   */-  bool abl_link_audio_sink_buffer_commit(struct abl_link_audio_sink_buffer_handle *handle,-    abl_link_session_state session_state,-    double beats_at_buffer_begin,-    double quantum,-    size_t num_frames,-    size_t num_channels,-    uint32_t sample_rate);--  /*! @brief Release a retained buffer without committing. The handle is invalid after-   *  this.-   *  Thread-safe: no-   *  Realtime-safe: yes-   */-  void abl_link_audio_sink_buffer_release(-    struct abl_link_audio_sink_buffer_handle *handle);--  /*! @brief Buffer metadata for received audio. */-  struct abl_link_audio_source_buffer_info-  {-    size_t num_channels;-    size_t num_frames;-    uint32_t sample_rate;-    uint64_t count;-    double session_beat_time;-    double tempo;-    struct abl_link_audio_session_id session_id;-  };--  /*! @brief Map the beat time at the begin of the buffer to the local Link session state.-   *  @return True if the buffer originates from the same Link Session and out_beats is-   *  set.-   */-  bool abl_link_audio_source_buffer_info_begin_beats(-    const struct abl_link_audio_source_buffer_info *info,-    abl_link_session_state session_state,-    double quantum,-    double *out_beats);--  /*! @brief Map the beat time at the end of the buffer to the local Link session state.-   *  @return True if the buffer originates from the same Link Session and out_beats is-   *  set.-   */-  bool abl_link_audio_source_buffer_info_end_beats(-    const struct abl_link_audio_source_buffer_info *info,-    abl_link_session_state session_state,-    double quantum,-    double *out_beats);--  /*! @brief Buffer provided to Link Audio source callbacks. */-  struct abl_link_audio_source_buffer-  {-    int16_t *samples;-    struct abl_link_audio_source_buffer_info info;-  };--  /*! @brief The representation of an abl_link_audio_source instance */-  struct abl_link_audio_source-  {-    void *impl;-  };--  /*! @brief Construct a Link Audio source for a given channel.-   *  @param callback Invoked on a Link-managed thread when a source buffer is received.-   *                  Neither the buffer pointer nor its samples pointer remain valid-   *                  after the callback returns.-   */-  struct abl_link_audio_source abl_link_audio_source_create(struct abl_link link,-    struct abl_link_audio_channel_id channel_id,-    void (*callback)(const struct abl_link_audio_source_buffer *buffer, void *context),-    void *context);--  /*! @brief Destroy a Link Audio source. */-  void abl_link_audio_source_destroy(struct abl_link_audio_source source);--  /*! @brief Get the channel ID of the corresponding source.-   *  Thread-safe: yes-   *  Realtime-safe: yes-   */-  struct abl_link_audio_channel_id abl_link_audio_source_id(-    struct abl_link_audio_source source);  #ifdef __cplusplus } // extern "C"
link/extensions/abl_link/src/abl_link.cpp view
@@ -18,135 +18,70 @@  */  #include <abl_link.h>-#include <ableton/LinkAudio.hpp>--#include <algorithm>-#include <cstdlib>-#include <cstring>-#include <string>--namespace-{-struct abl_link_audio_channel_id toChannelId(const ableton::link_audio::Id &id)-{-  struct abl_link_audio_channel_id out{};-  std::copy(id.begin(), id.end(), out.bytes);-  return out;-}--struct abl_link_audio_peer_id toPeerId(const ableton::link_audio::Id &id)-{-  struct abl_link_audio_peer_id out{};-  std::copy(id.begin(), id.end(), out.bytes);-  return out;-}--struct abl_link_audio_session_id toSessionId(const ableton::link_audio::Id &id)-{-  struct abl_link_audio_session_id out{};-  std::copy(id.begin(), id.end(), out.bytes);-  return out;-}--ableton::link_audio::Id toCppChannelId(const struct abl_link_audio_channel_id &id)-{-  ableton::link_audio::Id out{};-  std::copy(id.bytes, id.bytes + sizeof(id.bytes), out.begin());-  return out;-}--ableton::link_audio::Id toCppSessionId(const struct abl_link_audio_session_id &id)-{-  ableton::link_audio::Id out{};-  std::copy(id.bytes, id.bytes + sizeof(id.bytes), out.begin());-  return out;-}--char *copyCString(const std::string &value)-{-  auto *buffer = static_cast<char *>(std::malloc(value.size() + 1));-  if (buffer)-  {-    std::memcpy(buffer, value.c_str(), value.size() + 1);-  }-  return buffer;-}--size_t copyStringToBuffer(const std::string &src, char *buffer, size_t buffer_size)-{-  if (buffer && buffer_size > 0)-  {-    const auto toCopy = std::min(buffer_size - 1, src.size());-    std::memcpy(buffer, src.c_str(), toCopy);-    buffer[toCopy] = '\0';-  }-  return src.size();-}-} // namespace+#include <ableton/Link.hpp>  extern "C" {-  struct abl_link abl_link_create(double bpm)+  abl_link abl_link_create(double bpm)   {-    return {reinterpret_cast<void *>(new ableton::LinkAudio(bpm, std::string{}))};+    return abl_link{reinterpret_cast<void *>(new ableton::Link(bpm))};   } -  void abl_link_destroy(struct abl_link link)+  void abl_link_destroy(abl_link link)   {-    delete reinterpret_cast<ableton::LinkAudio *>(link.impl);+    delete reinterpret_cast<ableton::Link *>(link.impl);   } -  bool abl_link_is_enabled(struct abl_link link)+  bool abl_link_is_enabled(abl_link link)   {-    return reinterpret_cast<ableton::LinkAudio *>(link.impl)->isEnabled();+    return reinterpret_cast<ableton::Link *>(link.impl)->isEnabled();   } -  void abl_link_enable(struct abl_link link, bool enabled)+  void abl_link_enable(abl_link link, bool enabled)   {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->enable(enabled);+    reinterpret_cast<ableton::Link *>(link.impl)->enable(enabled);   } -  bool abl_link_is_start_stop_sync_enabled(struct abl_link link)+  bool abl_link_is_start_stop_sync_enabled(abl_link link)   {-    return reinterpret_cast<ableton::LinkAudio *>(link.impl)->isStartStopSyncEnabled();+    return reinterpret_cast<ableton::Link *>(link.impl)->isStartStopSyncEnabled();   } -  void abl_link_enable_start_stop_sync(struct abl_link link, bool enabled)+  void abl_link_enable_start_stop_sync(abl_link link, bool enabled)   {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->enableStartStopSync(enabled);+    reinterpret_cast<ableton::Link *>(link.impl)->enableStartStopSync(enabled);   } -  uint64_t abl_link_num_peers(struct abl_link link)+  uint64_t abl_link_num_peers(abl_link link)   {-    return reinterpret_cast<ableton::LinkAudio *>(link.impl)->numPeers();+    return reinterpret_cast<ableton::Link *>(link.impl)->numPeers();   } -  void abl_link_set_num_peers_callback(struct abl_link link,-    void (*callback)(uint64_t num_peers, void *context),-    void *context)+  void abl_link_set_num_peers_callback(+    abl_link link, abl_link_num_peers_callback callback, void *context)   {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->setNumPeersCallback(-      [callback, context](std::size_t numPeers)-      { (*callback)(static_cast<uint64_t>(numPeers), context); });+    reinterpret_cast<ableton::Link *>(link.impl)->setNumPeersCallback(+      [callback, context](+        std::size_t numPeers) { (*callback)(static_cast<uint64_t>(numPeers), context); });   }    void abl_link_set_tempo_callback(-    struct abl_link link, void (*callback)(double tempo, void *context), void *context)+    abl_link link, abl_link_tempo_callback callback, void *context)   {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->setTempoCallback(+    reinterpret_cast<ableton::Link *>(link.impl)->setTempoCallback(       [callback, context](double tempo) { (*callback)(tempo, context); });   }    void abl_link_set_start_stop_callback(-    struct abl_link link, void (*callback)(bool isPlaying, void *context), void *context)+    abl_link link, abl_link_start_stop_callback callback, void *context)   {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->setStartStopCallback(+    reinterpret_cast<ableton::Link *>(link.impl)->setStartStopCallback(       [callback, context](bool isPlaying) { (*callback)(isPlaying, context); });   } -  int64_t abl_link_clock_micros(struct abl_link link)+  int64_t abl_link_clock_micros(abl_link link)   {-    return reinterpret_cast<ableton::LinkAudio *>(link.impl)->clock().micros().count();+    return reinterpret_cast<ableton::Link *>(link.impl)->clock().micros().count();   }    abl_link_session_state abl_link_create_session_state(void)@@ -161,30 +96,30 @@   }    void abl_link_capture_app_session_state(-    struct abl_link link, abl_link_session_state session_state)+    abl_link link, abl_link_session_state session_state)   {     *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) =-      reinterpret_cast<ableton::LinkAudio *>(link.impl)->captureAppSessionState();+      reinterpret_cast<ableton::Link *>(link.impl)->captureAppSessionState();   }    void abl_link_commit_app_session_state(-    struct abl_link link, abl_link_session_state session_state)+    abl_link link, abl_link_session_state session_state)   {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->commitAppSessionState(+    reinterpret_cast<ableton::Link *>(link.impl)->commitAppSessionState(       *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl));   }    void abl_link_capture_audio_session_state(-    struct abl_link link, abl_link_session_state session_state)+    abl_link link, abl_link_session_state session_state)   {     *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl) =-      reinterpret_cast<ableton::LinkAudio *>(link.impl)->captureAudioSessionState();+      reinterpret_cast<ableton::Link *>(link.impl)->captureAudioSessionState();   }    void abl_link_commit_audio_session_state(-    struct abl_link link, abl_link_session_state session_state)+    abl_link link, abl_link_session_state session_state)   {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->commitAudioSessionState(+    reinterpret_cast<ableton::Link *>(link.impl)->commitAudioSessionState(       *reinterpret_cast<ableton::Link::SessionState *>(session_state.impl));   } @@ -231,14 +166,14 @@   }    void abl_link_force_beat_at_time(-    abl_link_session_state session_state, double beat, int64_t time, double quantum)+    abl_link_session_state session_state, double beat, uint64_t time, double quantum)   {     reinterpret_cast<ableton::Link::SessionState *>(session_state.impl)       ->forceBeatAtTime(beat, std::chrono::microseconds{time}, quantum);   }    void abl_link_set_is_playing(-    abl_link_session_state session_state, bool is_playing, int64_t time)+    abl_link_session_state session_state, bool is_playing, uint64_t time)   {     reinterpret_cast<ableton::Link::SessionState *>(session_state.impl)       ->setIsPlaying(is_playing, std::chrono::microseconds(time));@@ -250,9 +185,9 @@       ->isPlaying();   } -  int64_t abl_link_time_for_is_playing(abl_link_session_state session_state)+  uint64_t abl_link_time_for_is_playing(abl_link_session_state session_state)   {-    return static_cast<int64_t>(+    return static_cast<uint64_t>(       reinterpret_cast<ableton::Link::SessionState *>(session_state.impl)         ->timeForIsPlaying()         .count());@@ -268,299 +203,12 @@   void abl_link_set_is_playing_and_request_beat_at_time(     abl_link_session_state session_state,     bool is_playing,-    int64_t time,+    uint64_t time,     double beat,     double quantum)   {     reinterpret_cast<ableton::Link::SessionState *>(session_state.impl)       ->setIsPlayingAndRequestBeatAtTime(         is_playing, std::chrono::microseconds{time}, beat, quantum);-  }--  bool abl_link_audio_is_link_audio_enabled(struct abl_link link)-  {-    return reinterpret_cast<ableton::LinkAudio *>(link.impl)->isLinkAudioEnabled();-  }--  void abl_link_audio_enable_link_audio(struct abl_link link, bool enabled)-  {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->enableLinkAudio(enabled);-  }--  size_t abl_link_audio_peer_name(struct abl_link link, char *buffer, size_t buffer_size)-  {-    return copyStringToBuffer(-      reinterpret_cast<ableton::LinkAudio *>(link.impl)->peerName(), buffer, buffer_size);-  }--  void abl_link_audio_set_peer_name(struct abl_link link, const char *name)-  {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->setPeerName(name);-  }--  struct abl_link_audio_channel_list abl_link_audio_get_channels(struct abl_link link)-  {-    struct abl_link_audio_channel_list result{};-    const auto channels = reinterpret_cast<ableton::LinkAudio *>(link.impl)->channels();-    result.count = channels.size();-    if (result.count == 0)-    {-      return result;-    }--    result.channels = static_cast<struct abl_link_audio_channel *>(-      std::calloc(result.count, sizeof(struct abl_link_audio_channel)));-    if (!result.channels)-    {-      result.count = 0;-      return result;-    }--    for (size_t i = 0; i < result.count; ++i)-    {-      const auto &channel = channels[i];-      result.channels[i].id = toChannelId(channel.id);-      result.channels[i].peer_id = toPeerId(channel.peerId);-      result.channels[i].name = copyCString(channel.name);-      result.channels[i].peer_name = copyCString(channel.peerName);-    }--    return result;-  }--  void abl_link_audio_free_channel_list(struct abl_link_audio_channel_list list)-  {-    if (!list.channels)-    {-      return;-    }-    for (size_t i = 0; i < list.count; ++i)-    {-      std::free(const_cast<char *>(list.channels[i].name));-      std::free(const_cast<char *>(list.channels[i].peer_name));-    }-    std::free(list.channels);-  }--  void abl_link_audio_set_channels_changed_callback(-    struct abl_link link, void (*callback)(void *context), void *context)-  {-    reinterpret_cast<ableton::LinkAudio *>(link.impl)->setChannelsChangedCallback(-      [callback, context]()-      {-        if (callback)-        {-          (*callback)(context);-        }-      });-  }--  struct abl_link_audio_sink abl_link_audio_sink_create(-    struct abl_link link, const char *name, size_t max_num_samples)-  {-    return {reinterpret_cast<void *>(new ableton::LinkAudioSink(-      *reinterpret_cast<ableton::LinkAudio *>(link.impl), name, max_num_samples))};-  }--  void abl_link_audio_sink_destroy(struct abl_link_audio_sink sink)-  {-    delete reinterpret_cast<ableton::LinkAudioSink *>(sink.impl);-  }--  size_t abl_link_audio_sink_name(-    struct abl_link_audio_sink sink, char *buffer, size_t buffer_size)-  {-    return copyStringToBuffer(-      reinterpret_cast<ableton::LinkAudioSink *>(sink.impl)->name(), buffer, buffer_size);-  }--  void abl_link_audio_sink_set_name(struct abl_link_audio_sink sink, const char *name)-  {-    reinterpret_cast<ableton::LinkAudioSink *>(sink.impl)->setName(name);-  }--  void abl_link_audio_sink_request_max_num_samples(-    struct abl_link_audio_sink sink, size_t num_samples)-  {-    reinterpret_cast<ableton::LinkAudioSink *>(sink.impl)->requestMaxNumSamples(-      num_samples);-  }--  size_t abl_link_audio_sink_max_num_samples(struct abl_link_audio_sink sink)-  {-    return reinterpret_cast<ableton::LinkAudioSink *>(sink.impl)->maxNumSamples();-  }--  struct abl_link_audio_sink_buffer_handle abl_link_audio_sink_retain_buffer(-    struct abl_link_audio_sink sink)-  {-    struct abl_link_audio_sink_buffer_handle result{};-    auto *cppSink = reinterpret_cast<ableton::LinkAudioSink *>(sink.impl);-    auto *cppHandle = new ableton::LinkAudioSink::BufferHandle(*cppSink);-    result.impl = cppHandle;-    result.samples = cppHandle->samples;-    result.max_num_samples = cppHandle->maxNumSamples;-    return result;-  }--  bool abl_link_audio_sink_buffer_is_valid(-    const struct abl_link_audio_sink_buffer_handle *handle)-  {-    if (!handle || !handle->impl)-    {-      return false;-    }-    const auto *cppHandle =-      reinterpret_cast<const ableton::LinkAudioSink::BufferHandle *>(handle->impl);-    return static_cast<bool>(*cppHandle);-  }--  bool abl_link_audio_sink_buffer_commit(struct abl_link_audio_sink_buffer_handle *handle,-    abl_link_session_state session_state,-    double beats_at_buffer_begin,-    double quantum,-    size_t num_frames,-    size_t num_channels,-    uint32_t sample_rate)-  {-    if (!handle || !handle->impl)-    {-      return false;-    }-    auto *cppHandle =-      reinterpret_cast<ableton::LinkAudioSink::BufferHandle *>(handle->impl);-    const auto *state =-      reinterpret_cast<ableton::Link::SessionState *>(session_state.impl);-    const auto result = cppHandle->commit(-      *state, beats_at_buffer_begin, quantum, num_frames, num_channels, sample_rate);-    delete cppHandle;-    handle->impl = nullptr;-    handle->samples = nullptr;-    handle->max_num_samples = 0;-    return result;-  }--  void abl_link_audio_sink_buffer_release(-    struct abl_link_audio_sink_buffer_handle *handle)-  {-    if (!handle || !handle->impl)-    {-      return;-    }-    delete reinterpret_cast<ableton::LinkAudioSink::BufferHandle *>(handle->impl);-    handle->impl = nullptr;-    handle->samples = nullptr;-    handle->max_num_samples = 0;-  }--  bool abl_link_audio_source_buffer_info_begin_beats(-    const struct abl_link_audio_source_buffer_info *info,-    abl_link_session_state session_state,-    double quantum,-    double *out_beats)-  {-    if (!info || !out_beats || !session_state.impl)-    {-      return false;-    }-    if (info->sample_rate == 0)-    {-      return false;-    }-    auto cppInfo = ableton::LinkAudioSource::BufferHandle::Info{};-    cppInfo.numChannels = info->num_channels;-    cppInfo.numFrames = info->num_frames;-    cppInfo.sampleRate = info->sample_rate;-    cppInfo.count = info->count;-    cppInfo.sessionBeatTime = info->session_beat_time;-    cppInfo.tempo = info->tempo;-    cppInfo.sessionId = toCppSessionId(info->session_id);--    const auto *state =-      reinterpret_cast<const ableton::Link::SessionState *>(session_state.impl);-    const auto beats = cppInfo.beginBeats(*state, quantum);-    if (!beats)-    {-      return false;-    }-    *out_beats = *beats;-    return true;-  }--  bool abl_link_audio_source_buffer_info_end_beats(-    const struct abl_link_audio_source_buffer_info *info,-    abl_link_session_state session_state,-    double quantum,-    double *out_beats)-  {-    if (!info || !out_beats || !session_state.impl)-    {-      return false;-    }-    if (info->sample_rate == 0)-    {-      return false;-    }-    auto cppInfo = ableton::LinkAudioSource::BufferHandle::Info{};-    cppInfo.numChannels = info->num_channels;-    cppInfo.numFrames = info->num_frames;-    cppInfo.sampleRate = info->sample_rate;-    cppInfo.count = info->count;-    cppInfo.sessionBeatTime = info->session_beat_time;-    cppInfo.tempo = info->tempo;-    cppInfo.sessionId = toCppSessionId(info->session_id);--    const auto *state =-      reinterpret_cast<const ableton::Link::SessionState *>(session_state.impl);-    const auto beats = cppInfo.endBeats(*state, quantum);-    if (!beats)-    {-      return false;-    }-    *out_beats = *beats;-    return true;-  }--  struct abl_link_audio_source abl_link_audio_source_create(struct abl_link link,-    struct abl_link_audio_channel_id channel_id,-    void (*callback)(const struct abl_link_audio_source_buffer *buffer, void *context),-    void *context)-  {-    auto *cppLink = reinterpret_cast<ableton::LinkAudio *>(link.impl);-    const auto id = toCppChannelId(channel_id);-    return {reinterpret_cast<void *>(new ableton::LinkAudioSource(*cppLink, id,-      [callback, context](ableton::LinkAudioSource::BufferHandle handle)-      {-        if (!callback)-        {-          return;-        }-        struct abl_link_audio_source_buffer buffer{};-        buffer.samples = handle.samples;-        buffer.info.num_channels = handle.info.numChannels;-        buffer.info.num_frames = handle.info.numFrames;-        buffer.info.sample_rate = handle.info.sampleRate;-        buffer.info.count = handle.info.count;-        buffer.info.session_beat_time = handle.info.sessionBeatTime;-        buffer.info.tempo = handle.info.tempo;-        buffer.info.session_id = toSessionId(handle.info.sessionId);-        callback(&buffer, context);-      }))};-  }--  void abl_link_audio_source_destroy(struct abl_link_audio_source source)-  {-    delete reinterpret_cast<ableton::LinkAudioSource *>(source.impl);-  }--  struct abl_link_audio_channel_id abl_link_audio_source_id(-    struct abl_link_audio_source source)-  {-    if (!source.impl)-    {-      struct abl_link_audio_channel_id empty{};-      return empty;-    }-    return toChannelId(reinterpret_cast<ableton::LinkAudioSource *>(source.impl)->id());   } }
link/include/ableton/Link.hpp view
@@ -22,8 +22,7 @@  #pragma once -#include <ableton/link/ApiConfig.hpp>-+#include <ableton/platforms/Config.hpp> #include <chrono> #include <mutex> @@ -104,13 +103,13 @@    /*! @brief: Is start/stop synchronization enabled?    *  Thread-safe: yes-   *  Realtime-safe: yes+   *  Realtime-safe: no    */   bool isStartStopSyncEnabled() const;    /*! @brief: Enable start/stop synchronization.    *  Thread-safe: yes-   *  Realtime-safe: yes+   *  Realtime-safe: no    */   void enableStartStopSync(bool bEnable); @@ -245,9 +244,6 @@   public:     SessionState(const link::ApiState state, const bool bRespectQuantum); -    bool operator==(const SessionState& other) const;-    bool operator!=(const SessionState& other) const;-     /*! @brief: The tempo of the timeline, in Beats Per Minute.      *      *  @discussion This is a stable value that is appropriate for display@@ -365,23 +361,23 @@     /*! @brief: Convenience function to start or stop transport at a given time and      *  attempt to map the given beat to this time in context of the given quantum.      */-    void setIsPlayingAndRequestBeatAtTime(bool isPlaying,-                                          std::chrono::microseconds time,-                                          double beat,-                                          double quantum);+    void setIsPlayingAndRequestBeatAtTime(+      bool isPlaying, std::chrono::microseconds time, double beat, double quantum);    private:-    template <typename SessionState>-    friend const link::ApiState& detail::linkApiState(const SessionState& sessionState);-     friend BasicLink<Clock>;     link::ApiState mOriginalState;     link::ApiState mState;     bool mbRespectQuantum;   }; -protected:-  using Controller = ableton::link::ApiController<Clock>;+private:+  using Controller = ableton::link::Controller<link::PeerCountCallback,+    link::TempoCallback,+    link::StartStopStateCallback,+    Clock,+    link::platform::Random,+    link::platform::IoContext>;    std::mutex mCallbackMutex;   link::PeerCountCallback mPeerCountCallback = [](std::size_t) {};
link/include/ableton/Link.ipp view
@@ -30,14 +30,11 @@ inline typename BasicLink<Clock>::SessionState toSessionState(   const link::ClientState& state, const bool isConnected) {-  return {{state.timeline,-           state.timelineSessionId,-           {state.startStopState.isPlaying, state.startStopState.time}},-          isConnected};+  return {{state.timeline, {state.startStopState.isPlaying, state.startStopState.time}},+    isConnected}; } -inline link::IncomingClientState toIncomingClientState(-  const link::ApiState& state,+inline link::IncomingClientState toIncomingClientState(const link::ApiState& state,   const link::ApiState& originalState,   const std::chrono::microseconds timestamp) {@@ -47,8 +44,7 @@   const auto startStopState =     originalState.startStopState != state.startStopState       ? link::OptionalClientStartStopState{{state.startStopState.isPlaying,-                                            state.startStopState.time,-                                            timestamp}}+          state.startStopState.time, timestamp}}       : link::OptionalClientStartStopState{};   return {timeline, startStopState, timestamp}; }@@ -57,20 +53,16 @@  template <typename Clock> inline BasicLink<Clock>::BasicLink(const double bpm)-  : mController(-      link::Tempo(bpm),-      [this](const std::size_t peers)-      {+  : mController(link::Tempo(bpm),+      [this](const std::size_t peers) {         std::lock_guard<std::mutex> lock(mCallbackMutex);         mPeerCountCallback(peers);       },-      [this](const link::Tempo tempo)-      {+      [this](const link::Tempo tempo) {         std::lock_guard<std::mutex> lock(mCallbackMutex);         mTempoCallback(tempo);       },-      [this](const bool isPlaying)-      {+      [this](const bool isPlaying) {         std::lock_guard<std::mutex> lock(mCallbackMutex);         mStartStopCallback(isPlaying);       },@@ -171,8 +163,8 @@ // Link::SessionState  template <typename Clock>-inline BasicLink<Clock>::SessionState::SessionState(const link::ApiState state,-                                                    const bool bRespectQuantum)+inline BasicLink<Clock>::SessionState::SessionState(+  const link::ApiState state, const bool bRespectQuantum)   : mOriginalState(state)   , mState(state)   , mbRespectQuantum(bRespectQuantum)@@ -180,19 +172,6 @@ }  template <typename Clock>-inline bool BasicLink<Clock>::SessionState::operator==(const SessionState& other) const-{-  return std::tie(mOriginalState, mState, mbRespectQuantum)-         == std::tie(other.mOriginalState, other.mState, other.mbRespectQuantum);-}--template <typename Clock>-inline bool BasicLink<Clock>::SessionState::operator!=(const SessionState& other) const-{-  return !(operator==(other));-}--template <typename Clock> inline double BasicLink<Clock>::SessionState::tempo() const {   return mState.timeline.tempo.bpm();@@ -238,19 +217,18 @@ {   if (mbRespectQuantum)   {-    time = timeAtBeat(-      link::nextPhaseMatch(-        link::Beats{beatAtTime(time, quantum)}, link::Beats{beat}, link::Beats{quantum})-        .floating(),+    time = timeAtBeat(link::nextPhaseMatch(link::Beats{beatAtTime(time, quantum)},+                        link::Beats{beat}, link::Beats{quantum})+                        .floating(),       quantum);   }   forceBeatAtTime(beat, time, quantum); }  inline void forceBeatAtTimeImpl(link::Timeline& timeline,-                                const link::Beats beat,-                                const std::chrono::microseconds time,-                                const link::Beats quantum)+  const link::Beats beat,+  const std::chrono::microseconds time,+  const link::Beats quantum) {   // There are two components to the beat adjustment: a phase shift   // and a beat magnitude adjustment.
− link/include/ableton/LinkAudio.hpp
@@ -1,358 +0,0 @@-/*! @file LinkAudio.hpp- *  @copyright 2025, Ableton AG, Berlin. All rights reserved.- *  @brief Library for cross-device shared tempo, quantized beat grid, and sharing audio- *- *  @license:- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#define LINK_AUDIO YES--#include <ableton/link_audio/ApiConfig.hpp>--#include <memory>-#include <optional>-#include <string>-#include <vector>--namespace ableton-{--/*! @class LinkAudio and BasicLinkAudio- *  @brief LinkAudio provides the Link functionality plus audio sharing.- *  To enable audio sharing include this header and replace the Link class with the- *  LinkAudio and Link should not be used simultaneously.- *- *  @discussion- *  LinkAudio provides the same functionality as Link. See Link.hpp for the respective- *  documentation. On top of that, LinkAudio allows to announce and discover audio- *  channels in a Link session. When sending and receiving audio, the Link beat time grid- *  and quantum can be used to align audio from different peers.- *- *  Channels in a Link session are represented as sinks on the sending side and sources on- *  the receiving side.- *  Sinks only send audio if at least one corresponding source is present in the session.- *  Audio buffers are interleaved and samples are represented as 16-bit signed integers.- */--template <typename Clock>-class BasicLinkAudio : public BasicLink<Clock>-{-public:-  /*! @brief Construct with an initial tempo and local peer name for identification in the-   *  Link session. Names longer than 256 characters will be truncated.-   */-  BasicLinkAudio(double bpm, std::string name);--  ~BasicLinkAudio();--  /*! @brief Is audio currently enabled?-   *  Thread-safe: yes-   *  Realtime-safe: yes-   */-  bool isLinkAudioEnabled() const;--  /*! @brief Enable or disable audio.-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  void enableLinkAudio(bool bEnable);--  /*! @brief Get the local peer name for identification in the Link session.-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  std::string peerName() const;--  /*! @brief Change the local peer name for identification in the Link session.-   *  Names longer than 256 characters will be truncated.-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  void setPeerName(std::string name);--  /*! @brief Register a callback to be notified when the set of available-   *  audio channels changes. This will be called when channels are discovered or-   *  disappeared and when names change.-   *  Thread-safe: yes-   *  Realtime-safe: no-   *-   *  @discussion The callback is invoked on a Link-managed thread.-   *  @param callback The callback signature is: void ()-   */-  template <typename Callback>-  void setChannelsChangedCallback(Callback callback);--  /*! @struct Channel-   *  @brief Describes an audio channel available in the Link session.-   *  @discussion-   *  The unique identifiers for channels and peers are persistent for the lifetime of a-   *  channel. Names may change over time and are meant for display purposes.-   */-  struct Channel-  {-    ChannelId id;         /*!< Unique identifier for the channel. */-    std::string name;     /*!< Name of the channel. */-    PeerId peerId;        /*!< Identifier of the peer providing the channel. */-    std::string peerName; /*!< Name of the peer providing the channel. */-  };--  /*! @brief Get the list of currently available audio channels in the session.-   *  Thread-safe: yes-   *  Realtime-safe: no-   */-  std::vector<Channel> channels() const;--  /*! @brief Call a function on the Link thread.-   *  Thread-safe: yes-   *  Realtime-safe: no-   *-   *  @discussion The function will be called on the Link thread, which is managed by the-   *  LinkAudio instance. This is useful for setting the thread priority for example.-   *  @param func The function signature is: void ()-   */-  template <typename Function>-  void callOnLinkThread(Function func);--private:-  using Controller = ableton::link::ApiController<Clock>;--  link_audio::ChannelsChangedCallback mChannelsChangedCallback = []() {};-};--class LinkAudio : public BasicLinkAudio<link::platform::Clock>-{-public:-  using Clock = link::platform::Clock;--  LinkAudio(double bpm, std::string name)-    : BasicLinkAudio<Clock>(bpm, name)-  {-  }--private:-  friend class LinkAudioSink;-  friend class LinkAudioSource;-};--/*! @class LinkAudioSink- *  @brief Announces an audio channel to the Link session.- *- *  @discussion- *  The announced channel is visible to other peers for the lifetime of the sink.- *  The sink can be used to write audio samples, which will be sent to peers that have- *  respective sources.- */-class LinkAudioSink-{-public:-  /*! @brief Construct a LinkAudioSink with a LinkAudio instance, a name of the audio-   *  channel, and the maximum buffer size in samples. This buffer size should account for-   *  the number of channels times the number of samples per channel in one audio-   *  callback. Names longer than 256 characters will be truncated.-   */-  template <typename LinkAudio>-  LinkAudioSink(LinkAudio& link, std::string name, size_t maxNumSamples);--  LinkAudioSink(const LinkAudioSink&) = default;-  LinkAudioSink& operator=(const LinkAudioSink&) = default;-  LinkAudioSink(LinkAudioSink&&) = default;-  LinkAudioSink& operator=(LinkAudioSink&&) = default;--  /*! @brief Get the name of the channel.-   *  Thread-safe: no-   *  Realtime-safe: no-   */-  std::string name() const;--  /*! @brief Set the name of this channel. Names longer than 256 characters will be-   *  truncated.-   *  Thread-safe: no-   *  Realtime-safe: no-   */-  void setName(std::string name);--  /*! @brief Request a maximum buffer size for future buffers.-   *  Thread-safe: yes-   *  Realtime-safe: yes-   *-   *  @discussion Increase the number of samples retained buffer handles can hold. If the-   *  requested number of samples is smaller than the current maximum number of samples-   *  this is a no-op.-   */-  void requestMaxNumSamples(size_t numSamples);--  /*! @brief Get the current maximum number of samples a buffer handle can hold.-   *  Thread-safe: yes-   *  Realtime-safe: yes-   */-  size_t maxNumSamples() const;--  /*! @struct BufferHandle-   *  @brief Handle to a buffer for writing audio samples.-   */-  struct BufferHandle-  {-    /*! @brief Retain a buffer for writing audio samples. Only on BufferHandle can be-     *  retained at a time. A BufferHandle should never outlive the LinkAudioSink it was-     *  created from.-     *  Thread-safe: no-     *  Realtime-safe: yes-     */-    BufferHandle(LinkAudioSink&);--    BufferHandle(const BufferHandle&) = delete;-    BufferHandle(BufferHandle&& other) = delete;-    BufferHandle& operator=(const BufferHandle&) = delete;-    BufferHandle& operator=(BufferHandle&& other) = delete;--    ~BufferHandle();--    /*! @brief Check if the handle is valid. Make sure to check this before-     *  using the handle. The handle may be invalid if no corresponding source exists or-     *  no buffer is available.-     *-     *  Thread-safe: no-     *  Realtime-safe: yes-     */-    operator bool() const;-    int16_t* samples;     /*!< Pointer to the buffer for writing samples. */-    size_t maxNumSamples; /*!< Maximum number of samples that can be written. */---    /*! @brief Commit the buffer after writing samples. After this the buffer the object-     *  should not be used anymore.-     *  @param sessionState The current Link session state.-     *  @param beatsAtBufferBegin Beat at the start of the buffer.-     *  @param quantum Quantum value for beat mapping.-     *  @param numFrames Number of frames written. numFrames * numChannels may not exceed-     *  maxNumSamples.-     *  @param numChannels Number of channels. Can be 1 for mono or 2 for stereo.-     *  @param sampleRate Sample rate in Hz.-     *  @return True if the buffer was successfully committed.-     *-     *  Thread-safe: no-     *  Realtime-safe: yes-     *-     *  @discussion The Link session state, the quantum, and the beats at buffer begin-     *  must be same as used for rendering the audio locally. Changes to the Link session-     *  state should always be made before rendering and eventually writing the buffer.-     */-    template <typename SessionState>-    bool commit(const SessionState&,-                double beatsAtBufferBegin,-                double quantum,-                size_t numFrames,-                size_t numChannels,-                uint32_t sampleRate);--  private:-    std::weak_ptr<link_audio::Sink> mpSink;-    link_audio::Buffer<int16_t>* mpBuffer;-  };--private:-  friend struct BufferHandle;-  std::shared_ptr<link_audio::Sink> mpImpl;-};--/*! @class LinkAudioSource- *  @brief Receives audio streams from other peers in the Link session.- *- *  @discussion- *  LinkAudioSource allows an application to subscribe to an audio channel- *  published by another peer, receiving buffers as they become available.- */-class LinkAudioSource-{-public:-  struct BufferHandle;--  /*! @brief Construct a LinkAudioSource to receive audio for a specifc channel.-   *  @param link The LinkAudio instance.-   *  @param id The ID of the channel to be received.-   *  @param callback Callback invoked on a Link-managed thread when a buffer is received.-   *  The callback signature is: void (BufferHandle bufferHandle)-   */-  template <typename LinkAudio, typename Callback>-  LinkAudioSource(LinkAudio& link, ChannelId id, Callback callback);--  LinkAudioSource(const LinkAudioSource&) = default;-  LinkAudioSource& operator=(const LinkAudioSource&) = default;-  LinkAudioSource(LinkAudioSource&&) = default;-  LinkAudioSource& operator=(LinkAudioSource&&) = default;--  ~LinkAudioSource();--  /*! @brief Get the channel ID of the corresponding source.-   *  Thread-safe: yes-   *  Realtime-safe: yes-   */-  ChannelId id() const;--  /*! @struct BufferHandle-   *  @brief Handle to a buffer containing received audio samples.-   */-  struct BufferHandle-  {-    /*! @struct Info-     *  @brief Metadata about the received audio buffer.-     */-    struct Info-    {-      size_t numChannels;     /*!< Number of channels in the buffer. */-      size_t numFrames;       /*!< Number of frames in the buffer. */-      uint32_t sampleRate;    /*!< Sample rate in Hz. */-      uint64_t count;         /*!< Sequence number of the buffer. */-      double sessionBeatTime; /*!< Use beginBeats() to map this to local beat time. */-      double tempo;           /*!< Tempo in beats per minute. */-      SessionId sessionId;    /*!< ID of the session the buffer belongs to. */--      /*! @brief Map the beat time at the begin of the buffer to the local Link session-       *  state.-       *  @param sessionState The current Link session state.-       *  @param quantum Quantum value for beat mapping.-       *  @return Local beat time at buffer begin. Returns nullopt if the buffer-       *  originates from a different Link Session.-       */-      template <typename SessionState>-      std::optional<double> beginBeats(const SessionState&, double quantum) const;--      /*! @brief Map the beat time at the end of the buffer to the local Link session-       *  state.-       *  @param sessionState The current Link session state.-       *  @param quantum Quantum value for beat mapping.-       *  @return Local beat time at buffer end. Returns nullopt if the buffer-       *  originates from a different Link Session.-       */-      template <typename SessionState>-      std::optional<double> endBeats(const SessionState&, double quantum) const;-    };--    int16_t* samples; /*!< Pointer to the buffer of received samples. */-    Info info;        /*!< Information about the buffer. */-  };--private:-  std::shared_ptr<link_audio::Source> mpImpl;-};--} // namespace ableton--#include <ableton/LinkAudio.ipp>
− link/include/ableton/LinkAudio.ipp
@@ -1,267 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <string>--namespace ableton-{--template <typename Clock>-inline BasicLinkAudio<Clock>::BasicLinkAudio(const double bpm, std::string name)-  : BasicLink<Clock>(bpm)-{-  setPeerName(name);-  this->mController.setChannelsChangedCallback(-    [&]()-    {-      std::lock_guard<std::mutex> lock(this->mCallbackMutex);-      mChannelsChangedCallback();-    });-}--template <typename Clock>-inline BasicLinkAudio<Clock>::~BasicLinkAudio()-{-  this->mController.setChannelsChangedCallback([]() {});-}--template <typename Clock>-inline bool BasicLinkAudio<Clock>::isLinkAudioEnabled() const-{-  return this->mController.isLinkAudioEnabled();-}--template <typename Clock>-inline void BasicLinkAudio<Clock>::enableLinkAudio(const bool bEnable)-{-  this->mController.enableLinkAudio(bEnable);-}--template <typename Clock>-inline std::string BasicLinkAudio<Clock>::peerName() const-{-  return this->mController.name();-}--template <typename Clock>-inline void BasicLinkAudio<Clock>::setPeerName(std::string name)-{-  if (name.size() > link_audio::v1::kMaxNameSize)-  {-    name.resize(link_audio::v1::kMaxNameSize);-  }-  this->mController.setName(std::move(name));-}--template <typename Clock>-template <typename Callback>-inline void BasicLinkAudio<Clock>::setChannelsChangedCallback(Callback callback)-{-  std::lock_guard<std::mutex> lock(this->mCallbackMutex);-  mChannelsChangedCallback = callback;-}--template <typename Clock>-inline std::vector<typename BasicLinkAudio<Clock>::Channel> BasicLinkAudio<-  Clock>::channels() const-{-  auto channels = this->mController.channels();-  auto result = std::vector<typename BasicLinkAudio<Clock>::Channel>{};-  result.reserve(channels.size());-  for (auto& channel : channels)-  {-    result.push_back(typename BasicLinkAudio<Clock>::Channel{-      channel.id, channel.name, channel.peerId, channel.peerName});-  }-  return result;-}--template <typename Clock>-template <typename Function>-inline void BasicLinkAudio<Clock>::callOnLinkThread(Function func)-{-  this->mController.callOnLinkThread(std::move(func));-}--template <typename LinkAudio>-inline LinkAudioSink::LinkAudioSink(LinkAudio& link,-                                    std::string name,-                                    size_t maxNumSamples)-  : mpImpl{link.mController.addSink(name.size() > link_audio::v1::kMaxNameSize-                                      ? name.substr(0, link_audio::v1::kMaxNameSize)-                                      : std::move(name),-                                    maxNumSamples)}-{-}--inline std::string LinkAudioSink::name() const-{-  return mpImpl->name();-}--inline void LinkAudioSink::setName(std::string name)-{-  if (name.size() > link_audio::v1::kMaxNameSize)-  {-    name.resize(link_audio::v1::kMaxNameSize);-  }-  mpImpl->setName(std::move(name));-}--inline LinkAudioSink::BufferHandle::BufferHandle(LinkAudioSink& sink)-  : samples(nullptr)-  , maxNumSamples(0)-  , mpSink(sink.mpImpl)-  , mpBuffer(nullptr)-{-  if (auto pBuffer = sink.mpImpl->retainBuffer())-  {-    samples = pBuffer->mSamples.data();-    maxNumSamples = pBuffer->mSamples.size();-    mpBuffer = pBuffer;-  }-}--inline LinkAudioSink::BufferHandle::~BufferHandle()-{-  // BufferHandle should not outlive the LinkAudioSink it was created from-  assert(mpSink.lock());--  if (mpBuffer)-  {-    if (auto pSink = mpSink.lock())-    {-      pSink->releaseBuffer();-    }-  }-}--inline LinkAudioSink::BufferHandle::operator bool() const-{-  return mpBuffer != nullptr;-}--template <typename SessionState>-inline bool LinkAudioSink::BufferHandle::commit(const SessionState& sessionState,-                                                const double beatsAtBufferBegin,-                                                const double quantum,-                                                const size_t numFrames,-                                                const size_t numChannels,-                                                const uint32_t sampleRate)-{-  const auto result = static_cast<bool>(*this) && (numChannels == 1 || numChannels == 2)-                      && maxNumSamples >= numFrames * numChannels;--  if (result && mpBuffer)-  {-    if (auto pSink = mpSink.lock())-    {-      pSink->releaseAndCommitBuffer(detail::linkApiState(sessionState).timeline,-                                    detail::linkApiState(sessionState).timelineSessionId,-                                    beatsAtBufferBegin,-                                    quantum,-                                    numFrames,-                                    numChannels,-                                    sampleRate);-    }-  }--  mpBuffer = nullptr;--  return result;-}--template <typename SessionState>-inline std::optional<double> LinkAudioSource::BufferHandle::Info::beginBeats(-  const SessionState& sessionState, const double quantum) const-{-  const auto& state = detail::linkApiState(sessionState);-  if (state.timelineSessionId != sessionId)-  {-    return std::nullopt;-  }--  return link_audio::beatAtGlobalBeat(-           state.timeline, link::Beats{sessionBeatTime}, link::Beats{quantum})-    .floating();-}---template <typename SessionState>-inline std::optional<double> LinkAudioSource::BufferHandle::Info::endBeats(-  const SessionState& sessionState, const double quantum) const-{-  const auto& state = detail::linkApiState(sessionState);-  if (state.timelineSessionId != sessionId)-  {-    return std::nullopt;-  }--  const auto durationSeconds =-    static_cast<double>(numFrames) / static_cast<double>(sampleRate);-  const auto beatsPerSecond = tempo / 60.0;-  const auto endBeats = link::Beats{sessionBeatTime + durationSeconds * beatsPerSecond};-  return link_audio::beatAtGlobalBeat(state.timeline, endBeats, link::Beats{quantum})-    .floating();-}---template <typename LinkAudio, typename Callback>-inline LinkAudioSource::LinkAudioSource(LinkAudio& link, ChannelId id, Callback callback)-  : mpImpl{link.mController.addSource(-      std::move(id),-      [callback](auto handle)-      {-        auto info = LinkAudioSource::BufferHandle::Info{};-        info.numChannels = handle.mBuffer.mNumChannels;-        info.numFrames = handle.mBuffer.mNumFrames;-        info.sampleRate = handle.mBuffer.mSampleRate;-        info.count = handle.mBuffer.mCount;-        info.sessionBeatTime = handle.mBuffer.mBeginBeats.floating();-        info.tempo = handle.mBuffer.mTempo.bpm();-        info.sessionId = handle.mBuffer.mSessionId;--        callback(LinkAudioSource::BufferHandle{handle.mpSamples, info});-      })}-{-}--inline LinkAudioSource::~LinkAudioSource()-{-  mpImpl->setCallback([](auto) {});-}--inline void LinkAudioSink::requestMaxNumSamples(size_t numSamples)-{-  mpImpl->requestMaxNumSamples(numSamples);-}--inline size_t LinkAudioSink::maxNumSamples() const-{-  return mpImpl->maxNumSamples();-}--inline ChannelId LinkAudioSource::id() const-{-  return mpImpl->id();-}--} // namespace ableton
link/include/ableton/discovery/AsioTypes.hpp view
@@ -32,14 +32,8 @@ using UdpSocket = LINK_ASIO_NAMESPACE::ip::udp::socket; using UdpEndpoint = LINK_ASIO_NAMESPACE::ip::udp::endpoint; -template <typename... Args>-inline IpAddress makeAddress(Args&&... args)-{-  return LINK_ASIO_NAMESPACE::ip::make_address(std::forward<Args>(args)...);-}- template <typename AsioAddrType>-AsioAddrType makeAddressFromBytes(const char* pAddr)+AsioAddrType makeAddress(const char* pAddr) {   using namespace std;   typename AsioAddrType::bytes_type bytes;@@ -48,7 +42,7 @@ }  template <typename AsioAddrType>-AsioAddrType makeAddressFromBytes(const char* pAddr, uint32_t scopeId)+AsioAddrType makeAddress(const char* pAddr, uint32_t scopeId) {   using namespace std;   typename AsioAddrType::bytes_type bytes;
link/include/ableton/discovery/InterfaceScanner.hpp view
@@ -38,8 +38,8 @@   using Timer = typename util::Injected<IoContext>::type::Timer;    InterfaceScanner(const std::chrono::seconds period,-                   util::Injected<Callback> callback,-                   util::Injected<IoContext> io)+    util::Injected<Callback> callback,+    util::Injected<IoContext> io)     : mPeriod(period)     , mCallback(std::move(callback))     , mIo(std::move(io))@@ -73,14 +73,12 @@     // setup the next scanning     mTimer.expires_from_now(mPeriod);     using ErrorCode = typename Timer::ErrorCode;-    mTimer.async_wait(-      [this](const ErrorCode e)+    mTimer.async_wait([this](const ErrorCode e) {+      if (!e)       {-        if (!e)-        {-          scan();-        }-      });+        scan();+      }+    });   }  private:
link/include/ableton/discovery/IpInterface.hpp view
@@ -29,13 +29,15 @@  inline UdpEndpoint multicastEndpointV4() {-  return {makeAddress("224.76.78.75"), 20808};+  return {IpAddressV4::from_string("224.76.78.75"), 20808}; }  inline UdpEndpoint multicastEndpointV6(uint64_t scopeId) {   // This is a non-permanently-assigned link-local multicast address (RFC4291)-  return {makeAddress("ff12::8080%" + std::to_string(scopeId)), 20808};+  return {+    ::LINK_ASIO_NAMESPACE::ip::make_address("ff12::8080%" + std::to_string(scopeId)),+    20808}; }  // Type tags for dispatching between unicast and multicast packets@@ -70,9 +72,8 @@   }  -  std::size_t send(const uint8_t* const pData,-                   const size_t numBytes,-                   const UdpEndpoint& to)+  std::size_t send(+    const uint8_t* const pData, const size_t numBytes, const UdpEndpoint& to)   {     return mSendSocket.send(pData, numBytes, to);   }@@ -90,7 +91,10 @@       SocketReceiver<MulticastTag, Handler>(std::move(handler)));   } -  UdpEndpoint endpoint() const { return mSendSocket.endpoint(); }+  UdpEndpoint endpoint() const+  {+    return mSendSocket.endpoint();+  }  private:   template <typename Tag, typename Handler>@@ -116,8 +120,8 @@ };  template <std::size_t MaxPacketSize, typename IoContext>-IpInterface<IoContext, MaxPacketSize> makeIpInterface(util::Injected<IoContext> io,-                                                      const IpAddress& addr)+IpInterface<IoContext, MaxPacketSize> makeIpInterface(+  util::Injected<IoContext> io, const IpAddress& addr) {   return {std::move(io), addr}; }
link/include/ableton/discovery/NetworkByteStreamSerializable.hpp view
@@ -32,8 +32,6 @@  #include <chrono> #include <cstdint>-#include <iterator>-#include <string> #include <type_traits> #include <utility> #include <vector>@@ -87,7 +85,7 @@ // Default size implementation. Works for primitive types.  template <typename T,-          typename std::enable_if<std::is_fundamental<T>::value>::type* = nullptr>+  typename std::enable_if<std::is_fundamental<T>::value>::type* = nullptr> std::uint32_t sizeInByteStream(T) {   return sizeof(T);@@ -242,25 +240,6 @@   } }; -// int16_t in terms of uint16_t-template <typename It>-It toNetworkByteStream(int16_t i, It out)-{-  return toNetworkByteStream(reinterpret_cast<const uint16_t&>(i), std::move(out));-}--template <>-struct Deserialize<int16_t>-{-  template <typename It>-  static std::pair<int16_t, It> fromNetworkByteStream(It begin, It end)-  {-    auto result =-      Deserialize<uint16_t>::fromNetworkByteStream(std::move(begin), std::move(end));-    return std::make_pair(reinterpret_cast<const int16_t&>(result.first), result.second);-  }-};- // bool inline std::uint32_t sizeInByteStream(bool) {@@ -295,7 +274,7 @@ It toNetworkByteStream(const std::chrono::microseconds micros, It out) {   static_assert(sizeof(int64_t) == sizeof(std::chrono::microseconds::rep),-                "The size of microseconds::rep must match the size of int64_t.");+    "The size of microseconds::rep must matche the size of int64_t.");   return toNetworkByteStream(static_cast<int64_t>(micros.count()), std::move(out)); } @@ -312,34 +291,6 @@   } }; -// string-inline std::uint32_t sizeInByteStream(const std::string& str)-{-  return sizeof(std::uint32_t) + static_cast<std::uint32_t>(str.size());-}--template <typename It>-It toNetworkByteStream(const std::string& str, It out)-{-  static_assert(sizeof(std::uint8_t) == sizeof(char),-                "The size of char must match the size of uint8_t.");-  out = toNetworkByteStream(static_cast<std::uint32_t>(str.size()), out);-  return std::copy(str.begin(), str.end(), out);-}--template <>-struct Deserialize<std::string>-{-  template <typename It>-  static std::pair<std::string, It> fromNetworkByteStream(It bytesBegin, It bytesEnd)-  {-    const auto result = Deserialize<uint32_t>::fromNetworkByteStream(-      std::move(bytesBegin), std::move(bytesEnd));-    const auto endIt = std::next(result.second, result.first);-    return std::make_pair(std::string(result.second, endIt), endIt);-  }-};- namespace detail { @@ -368,9 +319,9 @@  template <typename T, typename BytesIt, typename InsertIt> BytesIt deserializeContainer(BytesIt bytesBegin,-                             const BytesIt bytesEnd,-                             InsertIt contBegin,-                             const std::uint32_t maxElements)+  const BytesIt bytesEnd,+  InsertIt contBegin,+  const std::uint32_t maxElements) {   using namespace std;   std::uint32_t numElements = 0;@@ -434,17 +385,15 @@ struct Deserialize<std::vector<T, Alloc>> {   template <typename It>-  static std::pair<std::vector<T, Alloc>, It> fromNetworkByteStream(It bytesBegin,-                                                                    It bytesEnd)+  static std::pair<std::vector<T, Alloc>, It> fromNetworkByteStream(+    It bytesBegin, It bytesEnd)   {     using namespace std;     auto result_size =       Deserialize<uint32_t>::fromNetworkByteStream(std::move(bytesBegin), bytesEnd);     vector<T, Alloc> result;     auto resultIt = detail::deserializeContainer<T>(std::move(result_size.second),-                                                    std::move(bytesEnd),-                                                    back_inserter(result),-                                                    result_size.first);+      std::move(bytesEnd), back_inserter(result), result_size.first);     return make_pair(std::move(result), std::move(resultIt));   } };@@ -489,9 +438,8 @@ It toNetworkByteStream(const std::tuple<X, Y, Z>& tup, It out) {   return toNetworkByteStream(-    std::get<2>(tup),-    toNetworkByteStream(-      std::get<1>(tup), toNetworkByteStream(std::get<0>(tup), std::move(out))));+    std::get<2>(tup), toNetworkByteStream(std::get<1>(tup),+                        toNetworkByteStream(std::get<0>(tup), std::move(out)))); }  template <typename X, typename Y, typename Z>
link/include/ableton/discovery/Payload.hpp view
@@ -166,8 +166,8 @@    // Concatenate payloads together into a single payload   template <typename RhsFirst, typename RhsRest>-  friend PayloadSum<RhsFirst, RhsRest> operator+(Payload lhs,-                                                 Payload<RhsFirst, RhsRest> rhs)+  friend PayloadSum<RhsFirst, RhsRest> operator+(+    Payload lhs, Payload<RhsFirst, RhsRest> rhs)   {     return {std::move(lhs.mFirst), std::move(lhs.mRest) + std::move(rhs)};   }@@ -200,7 +200,10 @@     return rhs;   } -  friend std::size_t sizeInByteStream(const Payload&) { return 0; }+  friend std::size_t sizeInByteStream(const Payload&)+  {+    return 0;+  }    template <typename It>   friend It toNetworkByteStream(const Payload&, It streamIt)@@ -233,7 +236,10 @@ template <> struct PayloadBuilder<> {-  Payload<> operator()() { return {}; }+  Payload<> operator()()+  {+    return {};+  } };  // Parse payloads to values@@ -252,17 +258,20 @@   }    template <typename It, typename FirstHandler, typename... RestHandlers>-  static void collectHandlers(detail::HandlerMap<It>& map,-                              FirstHandler handler,-                              RestHandlers... rest)+  static void collectHandlers(+    detail::HandlerMap<It>& map, FirstHandler handler, RestHandlers... rest)   {     using namespace std;-    map[First::key] = [handler](const It begin, const It end)-    {+    map[First::key] = [handler](const It begin, const It end) {       const auto res = First::fromNetworkByteStream(begin, end);       if (res.second != end)       {-        throw range_error("Parsing payload failed");+        std::ostringstream stringStream;+        stringStream << "Parsing payload entry " << First::key+                     << " did not consume the expected number of bytes. "+                     << " Expected: " << distance(begin, end)+                     << ", Actual: " << distance(begin, res.second);+        throw range_error(stringStream.str());       }       handler(res.first);     };
link/include/ableton/discovery/PeerGateway.hpp view
@@ -42,8 +42,8 @@   using TimerError = typename Timer::ErrorCode;    PeerGateway(util::Injected<Messenger> messenger,-              util::Injected<PeerObserver> observer,-              util::Injected<IoContext> io)+    util::Injected<PeerObserver> observer,+    util::Injected<IoContext> io)     : mpImpl(new Impl(std::move(messenger), std::move(observer), std::move(io)))   {     mpImpl->listen();@@ -57,7 +57,10 @@   {   } -  void updateState(NodeState state) { mpImpl->updateState(std::move(state)); }+  void updateState(NodeState state)+  {+    mpImpl->updateState(std::move(state));+  }  private:   using PeerTimeout = std::pair<std::chrono::system_clock::time_point, NodeId>;@@ -66,8 +69,8 @@   struct Impl : std::enable_shared_from_this<Impl>   {     Impl(util::Injected<Messenger> messenger,-         util::Injected<PeerObserver> observer,-         util::Injected<IoContext> io)+      util::Injected<PeerObserver> observer,+      util::Injected<IoContext> io)       : mMessenger(std::move(messenger))       , mObserver(std::move(observer))       , mIo(std::move(io))@@ -88,7 +91,10 @@       }     } -    void listen() { mMessenger->receive(util::makeAsyncSafe(this->shared_from_this())); }+    void listen()+    {+      mMessenger->receive(util::makeAsyncSafe(this->shared_from_this()));+    }      // Operators for handling incoming messages     void operator()(const PeerState<NodeState>& msg)@@ -144,13 +150,10 @@       const auto endExpired =         lower_bound(begin(mPeerTimeouts), end(mPeerTimeouts), test, TimeoutCompare{}); -      for_each(begin(mPeerTimeouts),-               endExpired,-               [this](const PeerTimeout& pto)-               {-                 info(mIo->log()) << "pruning peer " << pto.second;-                 peerTimedOut(*mObserver, pto.second);-               });+      for_each(begin(mPeerTimeouts), endExpired, [this](const PeerTimeout& pto) {+        info(mIo->log()) << "pruning peer " << pto.second;+        peerTimedOut(*mObserver, pto.second);+      });       mPeerTimeouts.erase(begin(mPeerTimeouts), endExpired);       scheduleNextPruning();     }@@ -168,14 +171,12 @@                           << mPeerTimeouts.front().second;          mPruneTimer.expires_at(t);-        mPruneTimer.async_wait(-          [this](const TimerError e)+        mPruneTimer.async_wait([this](const TimerError e) {+          if (!e)           {-            if (!e)-            {-              pruneExpiredPeers();-            }-          });+            pruneExpiredPeers();+          }+        });       }     } @@ -189,10 +190,8 @@      typename PeerTimeouts::iterator findPeer(const NodeId& peerId)     {-      return std::find_if(begin(mPeerTimeouts),-                          end(mPeerTimeouts),-                          [&peerId](const PeerTimeout& pto)-                          { return pto.second == peerId; });+      return std::find_if(begin(mPeerTimeouts), end(mPeerTimeouts),+        [&peerId](const PeerTimeout& pto) { return pto.second == peerId; });     }      util::Injected<Messenger> mMessenger;@@ -223,13 +222,12 @@ template <typename PeerObserver, typename StateQuery, typename IoContext> using Gateway =   PeerGateway<Messenger<StateQuery, typename util::Injected<IoContext>::type&>,-              PeerObserver,-              IoContext>;+    PeerObserver,+    IoContext>;  // Factory function to bind a PeerGateway to an IpInterface with the given address. template <typename PeerObserver, typename NodeState, typename IoContext>-Gateway<PeerObserver, NodeState, IoContext> makeGateway(-  util::Injected<IoContext> io,+Gateway<PeerObserver, NodeState, IoContext> makeGateway(util::Injected<IoContext> io,   const IpAddress& addr,   util::Injected<PeerObserver> observer,   NodeState state)
link/include/ableton/discovery/PeerGateways.hpp view
@@ -35,17 +35,15 @@ { public:   using IoType = typename util::Injected<IoContext>::type;-  using FactoryType = typename util::Injected<GatewayFactory>::type;-  using Gateway = std::invoke_result_t<FactoryType,-                                       NodeState,-                                       util::Injected<IoType&>,-                                       const discovery::IpAddress&>;+  using Gateway = decltype(std::declval<GatewayFactory>()(std::declval<NodeState>(),+    std::declval<util::Injected<IoType&>>(),+    std::declval<IpAddress>()));   using GatewayMap = std::map<IpAddress, Gateway>;    PeerGateways(const std::chrono::seconds rescanPeriod,-               NodeState state,-               util::Injected<GatewayFactory> factory,-               util::Injected<IoContext> io)+    NodeState state,+    GatewayFactory factory,+    util::Injected<IoContext> io)     : mIo(std::move(io))   {     mpScannerCallback =@@ -69,7 +67,6 @@   void enable(const bool bEnable)   {     mpScannerCallback->mGateways.clear();-    mpScannerCallback->mFactory->gatewaysChanged();     mpScanner->enable(bEnable);   } @@ -94,7 +91,6 @@   {     if (mpScannerCallback->mGateways.erase(gatewayAddr))     {-      mpScannerCallback->mFactory->gatewaysChanged();       // If we erased a gateway, rescan again immediately so that       // we will re-initialize it if it's still present       mpScanner->scan();@@ -104,7 +100,7 @@ private:   struct Callback   {-    Callback(NodeState state, util::Injected<GatewayFactory> factory, IoType& io)+    Callback(NodeState state, GatewayFactory factory, IoType& io)       : mState(std::move(state))       , mFactory(std::move(factory))       , mIo(io)@@ -118,26 +114,18 @@       // Get the set of current addresses.       vector<IpAddress> curAddrs;       curAddrs.reserve(mGateways.size());-      transform(std::begin(mGateways),-                std::end(mGateways),-                back_inserter(curAddrs),-                [](const typename GatewayMap::value_type& vt) { return vt.first; });+      transform(std::begin(mGateways), std::end(mGateways), back_inserter(curAddrs),+        [](const typename GatewayMap::value_type& vt) { return vt.first; });        // Now use set_difference to determine the set of addresses that       // are new and the set of cur addresses that are no longer there       vector<IpAddress> newAddrs;-      set_difference(std::begin(range),-                     std::end(range),-                     std::begin(curAddrs),-                     std::end(curAddrs),-                     back_inserter(newAddrs));+      set_difference(std::begin(range), std::end(range), std::begin(curAddrs),+        std::end(curAddrs), back_inserter(newAddrs));        vector<IpAddress> staleAddrs;-      set_difference(std::begin(curAddrs),-                     std::end(curAddrs),-                     std::begin(range),-                     std::end(range),-                     back_inserter(staleAddrs));+      set_difference(std::begin(curAddrs), std::end(curAddrs), std::begin(range),+        std::end(range), back_inserter(staleAddrs));        // Remove the stale addresses       for (const auto& addr : staleAddrs)@@ -151,7 +139,7 @@         try         {           info(mIo.log()) << "initializing peer gateway on interface " << addr;-          mGateways.emplace(addr, (*mFactory)(mState, util::injectRef(mIo), addr));+          mGateways.emplace(addr, mFactory(mState, util::injectRef(mIo), addr));         }         catch (const runtime_error& e)         {@@ -159,15 +147,10 @@                              << " reason: " << e.what();         }       }--      if (!staleAddrs.empty() || !newAddrs.empty())-      {-        mFactory->gatewaysChanged();-      }     }      NodeState mState;-    util::Injected<GatewayFactory> mFactory;+    GatewayFactory mFactory;     IoType& mIo;     GatewayMap mGateways;   };@@ -183,12 +166,13 @@ std::unique_ptr<PeerGateways<NodeState, GatewayFactory, IoContext>> makePeerGateways(   const std::chrono::seconds rescanPeriod,   NodeState state,-  util::Injected<GatewayFactory> factory,+  GatewayFactory factory,   util::Injected<IoContext> io) {+  using namespace std;   using Gateways = PeerGateways<NodeState, GatewayFactory, IoContext>;-  return std::make_unique<Gateways>(-    rescanPeriod, std::move(state), std::move(factory), std::move(io));+  return unique_ptr<Gateways>{+    new Gateways{rescanPeriod, std::move(state), std::move(factory), std::move(io)}}; }  } // namespace discovery
link/include/ableton/discovery/Service.hpp view
@@ -32,9 +32,7 @@ public:   using ServicePeerGateways = PeerGateways<NodeState, GatewayFactory, IoContext>; -  Service(NodeState state,-          util::Injected<GatewayFactory> factory,-          util::Injected<IoContext> io)+  Service(NodeState state, GatewayFactory factory, util::Injected<IoContext> io)     : mEnabled(false)     , mGateways(         std::chrono::seconds(5), std::move(state), std::move(factory), std::move(io))@@ -47,7 +45,10 @@     mGateways.enable(bEnable);   } -  bool isEnabled() const { return mEnabled; }+  bool isEnabled() const+  {+    return mEnabled;+  }    // Asynchronously operate on the current set of peer gateways. The   // handler will be invoked in the service's io context.@@ -57,7 +58,10 @@     mGateways.withGateways(std::move(handler));   } -  void updateNodeState(const NodeState& state) { mGateways.updateNodeState(state); }+  void updateNodeState(const NodeState& state)+  {+    mGateways.updateNodeState(state);+  }    // Repair the gateway with the given address if possible. Its   // sockets may have been closed, for example, and the gateway needs
link/include/ableton/discovery/UdpMessenger.hpp view
@@ -57,20 +57,20 @@ // Throws UdpSendException template <typename Interface, typename NodeId, typename Payload> void sendUdpMessage(Interface& iface,-                    NodeId from,-                    const uint8_t ttl,-                    const v1::MessageType messageType,-                    const Payload& payload,-                    const UdpEndpoint& to)+  NodeId from,+  const uint8_t ttl,+  const v1::MessageType messageType,+  const Payload& payload,+  const UdpEndpoint& to) {   using namespace std;   v1::MessageBuffer buffer;   const auto messageBegin = begin(buffer);+  const auto messageEnd =+    v1::detail::encodeMessage(std::move(from), ttl, messageType, payload, messageBegin);+  const auto numBytes = static_cast<size_t>(distance(messageBegin, messageEnd));   try   {-    const auto messageEnd =-      v1::detail::encodeMessage(std::move(from), ttl, messageType, payload, messageBegin);-    const auto numBytes = static_cast<size_t>(distance(messageBegin, messageEnd));     iface.send(buffer.data(), numBytes, to);   }   catch (const std::runtime_error& err)@@ -93,10 +93,10 @@   using TimePoint = typename Timer::TimePoint;    UdpMessenger(util::Injected<Interface> iface,-               NodeState state,-               util::Injected<IoContext> io,-               const uint8_t ttl,-               const uint8_t ttlRatio)+    NodeState state,+    util::Injected<IoContext> io,+    const uint8_t ttl,+    const uint8_t ttlRatio)     : mpImpl(std::make_shared<Impl>(         std::move(iface), std::move(state), std::move(io), ttl, ttlRatio))   {@@ -130,12 +130,18 @@     }   } -  void updateState(NodeState state) { mpImpl->updateState(std::move(state)); }+  void updateState(NodeState state)+  {+    mpImpl->updateState(std::move(state));+  }    // Broadcast the current state of the system to all peers. May throw   // std::runtime_error if assembling a broadcast message fails or if   // there is an error at the transport layer. Throws on failure.-  void broadcastState() { mpImpl->broadcastState(); }+  void broadcastState()+  {+    mpImpl->broadcastState();+  }    // Asynchronous receive function for incoming messages from peers. Will   // return immediately and the handler will be invoked when a message@@ -151,10 +157,10 @@   struct Impl : std::enable_shared_from_this<Impl>   {     Impl(util::Injected<Interface> iface,-         NodeState state,-         util::Injected<IoContext> io,-         const uint8_t ttl,-         const uint8_t ttlRatio)+      NodeState state,+      util::Injected<IoContext> io,+      const uint8_t ttl,+      const uint8_t ttlRatio)       : mIo(std::move(io))       , mInterface(std::move(iface))       , mState(std::move(state))@@ -170,8 +176,8 @@     template <typename Handler>     void setReceiveHandler(Handler handler)     {-      mPeerStateHandler = [handler](PeerState<NodeState> state)-      { handler(std::move(state)); };+      mPeerStateHandler = [handler](+                            PeerState<NodeState> state) { handler(std::move(state)); };        mByeByeHandler = [handler](ByeBye<NodeId> byeBye) { handler(std::move(byeBye)); };     }@@ -180,26 +186,20 @@     {       if (mInterface->endpoint().address().is_v4())       {-        sendUdpMessage(*mInterface,-                       mState.ident(),-                       0,-                       v1::kByeBye,-                       makePayload(),-                       multicastEndpointV4());+        sendUdpMessage(*mInterface, mState.ident(), 0, v1::kByeBye, makePayload(),+          multicastEndpointV4());       }       if (mInterface->endpoint().address().is_v6())       {-        sendUdpMessage(-          *mInterface,-          mState.ident(),-          0,-          v1::kByeBye,-          makePayload(),+        sendUdpMessage(*mInterface, mState.ident(), 0, v1::kByeBye, makePayload(),           multicastEndpointV6(mInterface->endpoint().address().to_v6().scope_id()));       }     } -    void updateState(NodeState state) { mState = std::move(state); }+    void updateState(NodeState state)+    {+      mState = std::move(state);+    }      void broadcastState()     {@@ -218,14 +218,12 @@       // scheduled to try again. We want to keep trying at our       // interval as long as this instance is alive.       mTimer.expires_from_now(delay > milliseconds{0} ? delay : nominalBroadcastPeriod);-      mTimer.async_wait(-        [this](const TimerError e)+      mTimer.async_wait([this](const TimerError e) {+        if (!e)         {-          if (!e)-          {-            broadcastState();-          }-        });+          broadcastState();+        }+      });        // If we're not delaying, broadcast now       if (delay < milliseconds{1})@@ -237,8 +235,7 @@         }         if (mInterface->endpoint().address().is_v6())         {-          sendPeerState(-            v1::kAlive,+          sendPeerState(v1::kAlive,             multicastEndpointV6(mInterface->endpoint().address().to_v6().scope_id()));         }       }@@ -246,16 +243,9 @@      void sendPeerState(const v1::MessageType messageType, const UdpEndpoint& to)     {-      try-      {-        sendUdpMessage(-          *mInterface, mState.ident(), mTtl, messageType, toPayload(mState), to);-        mLastBroadcastTime = mTimer.now();-      }-      catch (const UdpSendException& err)-      {-        debug(mIo->log()) << "Failed to send peer state message: " << err.what();-      }+      sendUdpMessage(+        *mInterface, mState.ident(), mTtl, messageType, toPayload(mState), to);+      mLastBroadcastTime = mTimer.now();     }      void sendResponse(const UdpEndpoint& to)@@ -271,10 +261,8 @@     }      template <typename Tag, typename It>-    void operator()(Tag tag,-                    const UdpEndpoint& from,-                    const It messageBegin,-                    const It messageEnd)+    void operator()(+      Tag tag, const UdpEndpoint& from, const It messageBegin, const It messageEnd)     {       auto result = v1::parseMessageHeader<NodeId>(messageBegin, messageEnd); @@ -282,33 +270,50 @@       // Ignore messages from self and other groups       if (header.ident != mState.ident() && header.groupId == 0)       {-        debug(mIo->log()) << "Received message type "-                          << static_cast<int>(header.messageType) << " from peer "-                          << header.ident;+        // On Linux multicast messages are sent to all sockets registered to the multicast+        // group. To avoid duplicate message handling and invalid response messages we+        // check if the message is coming from an endpoint that is in the same subnet as+        // the interface.+        auto ignoreIpV4Message = false;+        if (from.address().is_v4() && mInterface->endpoint().address().is_v4())+        {+          const auto subnet = LINK_ASIO_NAMESPACE::ip::make_network_v4(+            mInterface->endpoint().address().to_v4(), 24);+          const auto fromAddr =+            LINK_ASIO_NAMESPACE::ip::make_network_v4(from.address().to_v4(), 32);+          ignoreIpV4Message = !fromAddr.is_subnet_of(subnet);+        } -        switch (header.messageType)+        if (!ignoreIpV4Message)         {-        case v1::kAlive:-          sendResponse(from);-          receivePeerState(std::move(result.first), result.second, messageEnd);-          break;-        case v1::kResponse:-          receivePeerState(std::move(result.first), result.second, messageEnd);-          break;-        case v1::kByeBye:-          receiveByeBye(std::move(result.first.ident));-          break;-        default:-          info(mIo->log()) << "Unknown message received of type: " << header.messageType;+          debug(mIo->log()) << "Received message type "+                            << static_cast<int>(header.messageType) << " from peer "+                            << header.ident;++          switch (header.messageType)+          {+          case v1::kAlive:+            sendResponse(from);+            receivePeerState(std::move(result.first), result.second, messageEnd);+            break;+          case v1::kResponse:+            receivePeerState(std::move(result.first), result.second, messageEnd);+            break;+          case v1::kByeBye:+            receiveByeBye(std::move(result.first.ident));+            break;+          default:+            info(mIo->log()) << "Unknown message received of type: "+                             << header.messageType;+          }         }       }       listen(tag);     }      template <typename It>-    void receivePeerState(v1::MessageHeader<NodeId> header,-                          It payloadBegin,-                          It payloadEnd)+    void receivePeerState(+      v1::MessageHeader<NodeId> header, It payloadBegin, It payloadEnd)     {       try       {
− link/include/ableton/discovery/UnicastIpInterface.hpp
@@ -1,99 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/util/Injected.hpp>-#include <memory>-#include <stdexcept>--namespace ableton-{-namespace link_audio-{--template <typename IoContext, std::size_t MaxPacketSize>-class UnicastIpInterface-{-public:-  using Socket = typename util::Injected<IoContext>::type::template Socket<MaxPacketSize>;--  UnicastIpInterface(util::Injected<IoContext> io, const discovery::IpAddress& addr)-    : mSocket(io->template openUnicastSocket<MaxPacketSize>(addr))-  {-  }--  UnicastIpInterface(const UnicastIpInterface&) = delete;-  UnicastIpInterface& operator=(const UnicastIpInterface&) = delete;--  UnicastIpInterface(UnicastIpInterface&& rhs)-    : mSocket(std::move(rhs.mSocket))-  {-  }--  std::size_t send(const uint8_t* const pData,-                   const size_t numBytes,-                   const discovery::UdpEndpoint& to)-  {-    return mSocket.send(pData, numBytes, to);-  }--  template <typename Handler>-  void receive(Handler handler)-  {-    mSocket.receive(SocketReceiver<Handler>(std::move(handler)));-  }--  discovery::UdpEndpoint endpoint() const { return mSocket.endpoint(); }--private:-  template <typename Handler>-  struct SocketReceiver-  {-    SocketReceiver(Handler handler)-      : mHandler(std::move(handler))-    {-    }--    template <typename It>-    void operator()(const discovery::UdpEndpoint& from,-                    const It messageBegin,-                    const It messageEnd)-    {-      mHandler(from, messageBegin, messageEnd);-    }--    Handler mHandler;-  };--  Socket mSocket;-};--template <std::size_t MaxPacketSize, typename IoContext>-std::shared_ptr<UnicastIpInterface<IoContext, MaxPacketSize>>-makeSharedUnicastIpInterface(util::Injected<IoContext> io,-                             const discovery::IpAddress& addr)-{-  return std::make_shared<UnicastIpInterface<IoContext, MaxPacketSize>>(-    std::move(io), addr);-}--} // namespace link_audio-} // namespace ableton
link/include/ableton/discovery/test/Interface.hpp view
@@ -19,11 +19,7 @@  #pragma once -#include <ableton/discovery/AsioTypes.hpp> #include <ableton/util/Log.hpp>-#include <functional>-#include <utility>-#include <vector>  namespace ableton {@@ -42,9 +38,8 @@   {   } -  void send(const uint8_t* const bytes,-            const size_t numBytes,-            const UdpEndpoint& endpoint)+  void send(+    const uint8_t* const bytes, const size_t numBytes, const UdpEndpoint& endpoint)   {     sentMessages.push_back(       std::make_pair(std::vector<uint8_t>{bytes, bytes + numBytes}, endpoint));@@ -54,15 +49,9 @@   void receive(Callback callback, Tag tag)   {     mCallback = [callback, tag](-                  const UdpEndpoint& from, const std::vector<uint8_t>& buffer)-    { callback(tag, from, begin(buffer), end(buffer)); };-  }--  template <typename Callback>-  void receive(Callback callback)-  {-    mCallback = [callback](const auto& from, const auto& buffer)-    { callback(from, begin(buffer), end(buffer)); };+                  const UdpEndpoint& from, const std::vector<uint8_t>& buffer) {+      callback(tag, from, begin(buffer), end(buffer));+    };   }    template <typename It>@@ -72,7 +61,10 @@     mCallback(from, buffer);   } -  UdpEndpoint endpoint() const { return mEndpoint; }+  UdpEndpoint endpoint() const+  {+    return mEndpoint;+  }    using SentMessage = std::pair<std::vector<uint8_t>, UdpEndpoint>;   std::vector<SentMessage> sentMessages;
link/include/ableton/discovery/test/PayloadEntries.hpp view
@@ -122,7 +122,10 @@     return std::make_pair(std::move(foobar), std::move(result.second));   } -  FoobarTuple asTuple() const { return std::make_tuple(fooVals, barVals); }+  FoobarTuple asTuple() const+  {+    return std::make_tuple(fooVals, barVals);+  } };  } // namespace test
link/include/ableton/discovery/test/Socket.hpp view
@@ -33,13 +33,16 @@ class Socket { public:-  Socket(util::test::IoService&) {}+  Socket(util::test::IoService&)+  {+  } -  friend void configureUnicastSocket(Socket&, const IpAddressV4&) {}+  friend void configureUnicastSocket(Socket&, const IpAddressV4&)+  {+  } -  std::size_t send(const uint8_t* const pData,-                   const size_t numBytes,-                   const discovery::UdpEndpoint& to)+  std::size_t send(+    const uint8_t* const pData, const size_t numBytes, const discovery::UdpEndpoint& to)   {     sentMessages.push_back(       std::make_pair(std::vector<uint8_t>{pData, pData + numBytes}, to));@@ -49,8 +52,9 @@   template <typename Handler>   void receive(Handler handler)   {-    mCallback = [handler](const UdpEndpoint& from, const std::vector<uint8_t>& buffer)-    { handler(from, begin(buffer), end(buffer)); };+    mCallback = [handler](const UdpEndpoint& from, const std::vector<uint8_t>& buffer) {+      handler(from, begin(buffer), end(buffer));+    };   }    template <typename It>@@ -60,7 +64,10 @@     mCallback(from, buffer);   } -  UdpEndpoint endpoint() const { return UdpEndpoint({}, 0); }+  UdpEndpoint endpoint() const+  {+    return UdpEndpoint({}, 0);+  }    using SentMessage = std::pair<std::vector<uint8_t>, UdpEndpoint>;   std::vector<SentMessage> sentMessages;
link/include/ableton/discovery/v1/Messages.hpp view
@@ -61,12 +61,9 @@   template <typename It>   friend It toNetworkByteStream(const MessageHeader& header, It out)   {-    return discovery::toNetworkByteStream(-      header.ident,-      discovery::toNetworkByteStream(-        header.groupId,-        discovery::toNetworkByteStream(-          header.ttl,+    return discovery::toNetworkByteStream(header.ident,+      discovery::toNetworkByteStream(header.groupId,+        discovery::toNetworkByteStream(header.ttl,           discovery::toNetworkByteStream(header.messageType, std::move(out)))));   } @@ -100,10 +97,10 @@ // Must have at least kMaxMessageSize bytes available in the output stream template <typename NodeId, typename Payload, typename It> It encodeMessage(NodeId from,-                 const uint8_t ttl,-                 const MessageType messageType,-                 const Payload& payload,-                 It out)+  const uint8_t ttl,+  const MessageType messageType,+  const Payload& payload,+  It out) {   using namespace std;   const MessageHeader<NodeId> header = {messageType, ttl, 0, std::move(from)};@@ -113,9 +110,8 @@   if (messageSize < kMaxMessageSize)   {     return toNetworkByteStream(-      payload,-      toNetworkByteStream(-        header, copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out))));+      payload, toNetworkByteStream(header,+                 copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out))));   }   else   {
− link/include/ableton/link/ApiConfig.hpp
@@ -1,46 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#ifndef LINK_API_CONTROLLER--#include <ableton/platforms/Config.hpp>--#include <ableton/link/SessionController.hpp>--namespace ableton-{-namespace link-{--template <typename Clock>-using ApiController = SessionController<PeerCountCallback,-                                        TempoCallback,-                                        StartStopStateCallback,-                                        Clock,-                                        platform::Random,-                                        platform::IoContext>;--} // namespace link-} // namespace ableton--#define LINK_API_CONTROLLER YES--#endif
link/include/ableton/link/Beats.hpp view
@@ -42,13 +42,25 @@   {   } -  double floating() const { return static_cast<double>(mValue) / 1e6; }+  double floating() const+  {+    return static_cast<double>(mValue) / 1e6;+  } -  std::int64_t microBeats() const { return mValue; }+  std::int64_t microBeats() const+  {+    return mValue;+  } -  Beats operator-() const { return Beats{-mValue}; }+  Beats operator-() const+  {+    return Beats{-mValue};+  } -  friend Beats abs(const Beats b) { return Beats{std::abs(b.mValue)}; }+  friend Beats abs(const Beats b)+  {+    return Beats{std::abs(b.mValue)};+  }    friend Beats operator+(const Beats lhs, const Beats rhs)   {
link/include/ableton/link/ClientSessionTimelines.hpp view
@@ -33,8 +33,7 @@   const double kMinBpm = 20.0;   const double kMaxBpm = 999.0;   return {Tempo{(std::min)((std::max)(timeline.tempo.bpm(), kMinBpm), kMaxBpm)},-          timeline.beatOrigin,-          timeline.timeOrigin};+    timeline.beatOrigin, timeline.timeOrigin}; }  // Given an existing client timeline, a session timeline, and the@@ -43,9 +42,9 @@ // previous timeline so that curClient.toBeats(atTime) == // result.toBeats(atTime). inline Timeline updateClientTimelineFromSession(const Timeline curClient,-                                                const Timeline session,-                                                const std::chrono::microseconds atTime,-                                                const GhostXForm xform)+  const Timeline session,+  const std::chrono::microseconds atTime,+  const GhostXForm xform) {   // An intermediate timeline representing the continuation of the   // existing client timeline with the tempo from the session timeline.@@ -64,9 +63,9 @@   inline Timeline updateSessionTimelineFromClient(const Timeline curSession,-                                                const Timeline client,-                                                const std::chrono::microseconds atTime,-                                                const GhostXForm xform)+  const Timeline client,+  const std::chrono::microseconds atTime,+  const GhostXForm xform) {   // The client timeline was constructed so that it's timeOrigin   // corresponds to beat 0 on the session timeline.@@ -95,7 +94,7 @@     // but we must also make sure that it's > curSession.beatOrigin     // because otherwise it will get ignored.     const auto newBeatOrigin = (std::max)(curSession.toBeats(xform.hostToGhost(atTime)),-                                          curSession.beatOrigin + Beats{INT64_C(1)});+      curSession.beatOrigin + Beats{INT64_C(1)});     return {client.tempo, newBeatOrigin, tempTl.fromBeats(newBeatOrigin)};   } }
link/include/ableton/link/Controller.hpp view
@@ -28,9 +28,7 @@ #include <ableton/link/SessionState.hpp> #include <ableton/link/Sessions.hpp> #include <ableton/link/StartStopState.hpp>-#include <ableton/util/TripleBuffer.hpp>--#include <chrono>+#include <ableton/link/TripleBuffer.hpp> #include <condition_variable> #include <mutex> @@ -54,27 +52,22 @@ {   using namespace std::chrono;   return {clampTempo(Timeline{tempo, Beats{0.}, microseconds{0}}),-          StartStopState{false, Beats{0.}, microseconds{0}},-          initXForm(clock)};+    StartStopState{false, Beats{0.}, microseconds{0}}, initXForm(clock)}; } -inline ClientState initClientState(const SessionState& sessionState, SessionId sessionId)+inline ClientState initClientState(const SessionState& sessionState) {   const auto hostTime = sessionState.ghostXForm.ghostToHost(std::chrono::microseconds{0});   return {     Timeline{sessionState.timeline.tempo, sessionState.timeline.beatOrigin, hostTime},-    std::move(sessionId),     ClientStartStopState{sessionState.startStopState.isPlaying, hostTime, hostTime}}; }  inline RtClientState initRtClientState(const ClientState& clientState) {   using namespace std::chrono;-  return {clientState.timeline,-          clientState.timelineSessionId,-          clientState.startStopState,-          microseconds{0},-          microseconds{0}};+  return {+    clientState.timeline, clientState.startStopState, microseconds{0}, microseconds{0}}; }  // The timespan in which local modifications to the timeline will be@@ -123,55 +116,50 @@  // The main Link controller template <typename PeerCountCallback,-          typename TempoCallback,-          typename StartStopStateCallback,-          typename Clock,-          typename Random,-          typename IoContext,-          typename SessionController>+  typename TempoCallback,+  typename StartStopStateCallback,+  typename Clock,+  typename Random,+  typename IoContext> class Controller { public:   Controller(Tempo tempo,-             PeerCountCallback peerCallback,-             TempoCallback tempoCallback,-             StartStopStateCallback startStopStateCallback,-             Clock clock)+    PeerCountCallback peerCallback,+    TempoCallback tempoCallback,+    StartStopStateCallback startStopStateCallback,+    Clock clock)     : mTempoCallback(std::move(tempoCallback))     , mStartStopStateCallback(std::move(startStopStateCallback))     , mClock(std::move(clock))     , mNodeId(NodeId::random<Random>())     , mSessionId(mNodeId)     , mSessionState(detail::initSessionState(tempo, mClock))-    , mClientState(detail::initClientState(mSessionState, mSessionId))+    , mClientState(detail::initClientState(mSessionState))     , mLastIsPlayingForStartStopStateCallback(false)     , mRtClientState(detail::initRtClientState(mClientState.get()))     , mHasPendingRtClientStates(false)-    , mpSessionController{static_cast<SessionController*>(this)}     , mSessionPeerCounter(*this, std::move(peerCallback))     , mEnabled(false)     , mStartStopSyncEnabled(false)     , mIo(IoContext{UdpSendExceptionHandler{this}})+    , mRtClientStateSetter(*this)     , mPeers(util::injectRef(*mIo),-             SessionMembershipCallback{this},-             SessionTimelineCallback{*this},-             SessionStartStopStateCallback{*this},-             SawAudioEndpointCallback{this})+        std::ref(mSessionPeerCounter),+        SessionTimelineCallback{*this},+        SessionStartStopStateCallback{*this})     , mSessions(         {mSessionId, mSessionState.timeline, {mSessionState.ghostXForm, mClock.micros()}},         util::injectRef(mPeers),-        MeasurePeer{this},-        JoinSessionCallback{this},+        MeasurePeer{*this},+        JoinSessionCallback{*this},         util::injectRef(*mIo),         mClock)-    , mDiscovery(-        std::make_pair(-          NodeState{-            mNodeId, mSessionId, mSessionState.timeline, mSessionState.startStopState},-          mSessionState.ghostXForm),-        util::injectVal(GatewayFactory{this}),+    , mDiscovery(std::make_pair(NodeState{mNodeId, mSessionId, mSessionState.timeline,+                                  mSessionState.startStopState},+                   mSessionState.ghostXForm),+        GatewayFactory{*this},         util::injectRef(*mIo))-    , mRtClientStateSetter(*this)   {   } @@ -181,6 +169,26 @@   Controller& operator=(const Controller&) = delete;   Controller& operator=(Controller&&) = delete; +  ~Controller()+  {+    std::mutex mutex;+    std::condition_variable condition;+    auto stopped = false;++    mIo->async([this, &mutex, &condition, &stopped]() {+      mEnabled = false;+      mDiscovery.enable(false);+      std::unique_lock<std::mutex> lock(mutex);+      stopped = true;+      condition.notify_one();+    });++    std::unique_lock<std::mutex> lock(mutex);+    condition.wait(lock, [&stopped] { return stopped; });++    mIo->stop();+  }+   void enable(const bool bEnable)   {     const bool bWasEnabled = mEnabled.exchange(bEnable);@@ -190,38 +198,51 @@     }   } -  bool isEnabled() const { return mEnabled; }+  bool isEnabled() const+  {+    return mEnabled;+  } -  void enableStartStopSync(const bool bEnable) { mStartStopSyncEnabled = bEnable; }+  void enableStartStopSync(const bool bEnable)+  {+    mStartStopSyncEnabled = bEnable;+  } -  bool isStartStopSyncEnabled() const { return mStartStopSyncEnabled; }+  bool isStartStopSyncEnabled() const+  {+    return mStartStopSyncEnabled;+  } -  std::size_t numPeers() const { return mSessionPeerCounter.mSessionPeerCount; }+  std::size_t numPeers() const+  {+    return mSessionPeerCounter.mSessionPeerCount;+  }    // Get the current Link client state. Thread-safe but may block, so   // it cannot be used from audio thread.-  ClientState clientState() const { return mClientState.get(); }+  ClientState clientState() const+  {+    return mClientState.get();+  }    // Set the client state to be used, starting at the given time.   // Thread-safe but may block, so it cannot be used from audio thread.   void setClientState(IncomingClientState newClientState)   {-    mClientState.update(-      [&](ClientState& clientState)+    mClientState.update([&](ClientState& clientState) {+      if (newClientState.timeline)       {-        if (newClientState.timeline)-        {-          *newClientState.timeline = clampTempo(*newClientState.timeline);-          clientState.timeline = *newClientState.timeline;-        }-        if (newClientState.startStopState)-        {-          // Prevent updating client start stop state with an outdated start stop state-          *newClientState.startStopState = detail::selectPreferredStartStopState(-            clientState.startStopState, *newClientState.startStopState);-          clientState.startStopState = *newClientState.startStopState;-        }-      });+        *newClientState.timeline = clampTempo(*newClientState.timeline);+        clientState.timeline = *newClientState.timeline;+      }+      if (newClientState.startStopState)+      {+        // Prevent updating client start stop state with an outdated start stop state+        *newClientState.startStopState = detail::selectPreferredStartStopState(+          clientState.startStopState, *newClientState.startStopState);+        clientState.startStopState = *newClientState.startStopState;+      }+    });     mIo->async([this, newClientState] { handleClientState(newClientState); });   } @@ -246,22 +267,20 @@       {         const auto clientState = mClientState.getRt(); -        if (timelineGracePeriodOver)+        if (timelineGracePeriodOver && clientState.timeline != mRtClientState.timeline)         {           mRtClientState.timeline = clientState.timeline;-          mRtClientState.timelineSessionId = clientState.timelineSessionId;         } -        if (startStopStateGracePeriodOver)+        if (startStopStateGracePeriodOver+            && clientState.startStopState != mRtClientState.startStopState)         {           mRtClientState.startStopState = clientState.startStopState;         }       }     } -    return {mRtClientState.timeline,-            mRtClientState.timelineSessionId,-            mRtClientState.startStopState};+    return {mRtClientState.timeline, mRtClientState.startStopState};   }    // should only be called from the audio thread@@ -303,7 +322,7 @@     }   } -protected:+private:   std::chrono::microseconds makeRtTimestamp(const std::chrono::microseconds now) const   {     return isEnabled() ? now : std::chrono::microseconds(0);@@ -313,13 +332,11 @@   {     bool shouldInvokeCallback = false; -    mClientState.update(-      [&](ClientState& clientState)-      {-        shouldInvokeCallback =-          mLastIsPlayingForStartStopStateCallback != clientState.startStopState.isPlaying;-        mLastIsPlayingForStartStopStateCallback = clientState.startStopState.isPlaying;-      });+    mClientState.update([&](ClientState& clientState) {+      shouldInvokeCallback =+        mLastIsPlayingForStartStopStateCallback != clientState.startStopState.isPlaying;+      mLastIsPlayingForStartStopStateCallback = clientState.startStopState.isPlaying;+    });      if (shouldInvokeCallback)     {@@ -330,10 +347,10 @@   void updateDiscovery()   {     // Push the change to the discovery service-    mDiscovery.updateNodeState(std::make_pair(-      NodeState{-        mNodeId, mSessionId, mSessionState.timeline, mSessionState.startStopState},-      mSessionState.ghostXForm));+    mDiscovery.updateNodeState(+      std::make_pair(NodeState{mNodeId, mSessionId, mSessionState.timeline,+                       mSessionState.startStopState},+        mSessionState.ghostXForm));   }    void updateSessionTiming(Timeline newTimeline, const GhostXForm newXForm)@@ -353,26 +370,19 @@       }        // Update the client timeline and start stop state based on the new session timing-      mClientState.update(-        [&](ClientState& clientState)+      mClientState.update([&](ClientState& clientState) {+        clientState.timeline = updateClientTimelineFromSession(clientState.timeline,+          mSessionState.timeline, mClock.micros(), mSessionState.ghostXForm);+        // Don't pass the start stop state to the client when start stop sync is disabled+        // or when we have a default constructed start stop state+        if (mStartStopSyncEnabled && mSessionState.startStopState != StartStopState{})         {-          clientState.timeline =-            updateClientTimelineFromSession(clientState.timeline,-                                            mSessionState.timeline,-                                            mClock.micros(),-                                            mSessionState.ghostXForm);-          clientState.timelineSessionId = mSessionId;-          // Don't pass the start stop state to the client when start stop sync is-          // disabled or when we have a default constructed start stop state-          if (mStartStopSyncEnabled && mSessionState.startStopState != StartStopState{})-          {-            std::lock_guard<std::mutex> startStopStateLock(mSessionStateGuard);-            clientState.startStopState =-              detail::mapStartStopStateFromSessionToClient(mSessionState.startStopState,-                                                           mSessionState.timeline,-                                                           mSessionState.ghostXForm);-          }-        });+          std::lock_guard<std::mutex> startStopStateLock(mSessionStateGuard);+          clientState.startStopState =+            detail::mapStartStopStateFromSessionToClient(mSessionState.startStopState,+              mSessionState.timeline, mSessionState.ghostXForm);+        }+      });        if (oldTimeline.tempo != newTimeline.tempo)       {@@ -386,11 +396,14 @@     debug(mIo->log()) << "Received timeline with tempo: " << timeline.tempo.bpm()                       << " for session: " << id;     updateSessionTiming(mSessions.sawSessionTimeline(std::move(id), std::move(timeline)),-                        mSessionState.ghostXForm);-    mpSessionController->updateDiscoveryCallback();+      mSessionState.ghostXForm);+    updateDiscovery();   } -  void resetSessionStartStopState() { mSessionState.startStopState = StartStopState{}; }+  void resetSessionStartStopState()+  {+    mSessionState.startStopState = StartStopState{};+  }    void handleStartStopStateFromSession(SessionId sessionId, StartStopState startStopState)   {@@ -406,16 +419,14 @@        // Always propagate the session start stop state so even a client that doesn't have       // the feature enabled can function as a relay.-      mpSessionController->updateDiscoveryCallback();+      updateDiscovery();        if (mStartStopSyncEnabled)       {-        mClientState.update(-          [&](ClientState& clientState)-          {-            clientState.startStopState = detail::mapStartStopStateFromSessionToClient(-              startStopState, mSessionState.timeline, mSessionState.ghostXForm);-          });+        mClientState.update([&](ClientState& clientState) {+          clientState.startStopState = detail::mapStartStopStateFromSessionToClient(+            startStopState, mSessionState.timeline, mSessionState.ghostXForm);+        });         invokeStartStopStateCallbackIfChanged();       }     }@@ -427,11 +438,8 @@      if (clientState.timeline)     {-      auto sessionTimeline =-        updateSessionTimelineFromClient(mSessionState.timeline,-                                        *clientState.timeline,-                                        clientState.timelineTimestamp,-                                        mSessionState.ghostXForm);+      auto sessionTimeline = updateSessionTimelineFromClient(mSessionState.timeline,+        *clientState.timeline, clientState.timelineTimestamp, mSessionState.ghostXForm);        mSessions.resetTimeline(sessionTimeline);       mPeers.setSessionTimeline(mSessionId, sessionTimeline);@@ -447,15 +455,12 @@         mSessionState.ghostXForm.hostToGhost(clientState.startStopState->timestamp);       if (newGhostTime > mSessionState.startStopState.timestamp)       {-        mClientState.update(-          [&](ClientState& currentClientState)-          {-            mSessionState.startStopState =-              detail::mapStartStopStateFromClientToSession(*clientState.startStopState,-                                                           mSessionState.timeline,-                                                           mSessionState.ghostXForm);-            currentClientState.startStopState = *clientState.startStopState;-          });+        mClientState.update([&](ClientState& currentClientState) {+          mSessionState.startStopState =+            detail::mapStartStopStateFromClientToSession(*clientState.startStopState,+              mSessionState.timeline, mSessionState.ghostXForm);+          currentClientState.startStopState = *clientState.startStopState;+        });          mustUpdateDiscovery = true;       }@@ -463,7 +468,7 @@      if (mustUpdateDiscovery)     {-      mpSessionController->updateDiscoveryCallback();+      updateDiscovery();     }      invokeStartStopStateCallbackIfChanged();@@ -471,21 +476,19 @@    void handleRtClientState(IncomingClientState clientState)   {-    mClientState.update(-      [&](ClientState& currentClientState)+    mClientState.update([&](ClientState& currentClientState) {+      if (clientState.timeline)       {-        if (clientState.timeline)-        {-          currentClientState.timeline = *clientState.timeline;-        }-        if (clientState.startStopState)-        {-          // Prevent updating client start stop state with an outdated start stop state-          *clientState.startStopState = detail::selectPreferredStartStopState(-            currentClientState.startStopState, *clientState.startStopState);-          currentClientState.startStopState = *clientState.startStopState;-        }-      });+        currentClientState.timeline = *clientState.timeline;+      }+      if (clientState.startStopState)+      {+        // Prevent updating client start stop state with an outdated start stop state+        *clientState.startStopState = detail::selectPreferredStartStopState(+          currentClientState.startStopState, *clientState.startStopState);+        currentClientState.startStopState = *clientState.startStopState;+      }+    });      handleClientState(clientState);     mHasPendingRtClientStates = false;@@ -504,13 +507,13 @@     }      updateSessionTiming(session.timeline, session.measurement.xform);-    mpSessionController->updateDiscoveryCallback();+    updateDiscovery();      if (sessionIdChanged)     {       debug(mIo->log()) << "Joining session " << session.sessionId << " with tempo "                         << session.timeline.tempo.bpm();-      mpSessionController->sessionMembershipCallback();+      mSessionPeerCounter();     }   } @@ -525,15 +528,14 @@     // the beat on the old session timeline corresponding to the     // current host time and mapping it to the new ghost time     // representation of the current host time.-    const auto newTl = Timeline{-      mSessionState.timeline.tempo,+    const auto newTl = Timeline{mSessionState.timeline.tempo,       mSessionState.timeline.toBeats(mSessionState.ghostXForm.hostToGhost(hostTime)),       xform.hostToGhost(hostTime)};      resetSessionStartStopState();      updateSessionTiming(newTl, xform);-    mpSessionController->updateDiscoveryCallback();+    updateDiscovery();      mSessions.resetSession({mNodeId, newTl, {xform, hostTime}});     mPeers.resetPeers();@@ -553,25 +555,27 @@   {     using CallbackDispatcher =       typename IoContext::template LockFreeCallbackDispatcher<std::function<void()>,-                                                              std::chrono::milliseconds>;+        std::chrono::milliseconds>;      RtClientStateSetter(Controller& controller)       : mController(controller)       , mCallbackDispatcher(-          [this]-          {-            mController.mIo->async(-              [this]() { mController.mpSessionController->updateRtStatesCallback(); });+          [this] {+            mController.mIo->async([this]() {+              // Process the pending client states first to make sure we don't push one+              // after we have joined a running session when enabling+              processPendingClientStates();+              updateEnabled();+            });           },           detail::kRtHandlerFallbackPeriod)     {     } -    void start() { mCallbackDispatcher.start(); }--    void stop() { mCallbackDispatcher.stop(); }--    void invoke() { mCallbackDispatcher.invoke(); }+    void invoke()+    {+      mCallbackDispatcher.invoke();+    }      void push(const IncomingClientState clientState)     {@@ -631,8 +635,8 @@     Controller& mController;     // Use separate TripleBuffers for the Timeline and the StartStopState so we read the     // latest set value from either optional.-    util::TripleBuffer<std::pair<std::chrono::microseconds, Timeline>> mTimelineBuffer;-    util::TripleBuffer<ClientStartStopState> mStartStopStateBuffer;+    TripleBuffer<std::pair<std::chrono::microseconds, Timeline>> mTimelineBuffer;+    TripleBuffer<ClientStartStopState> mStartStopStateBuffer;     CallbackDispatcher mCallbackDispatcher;   }; @@ -646,26 +650,6 @@     Controller& mController;   }; -  struct SawAudioEndpointCallback-  {-    void operator()(NodeId peerId,-                    std::optional<discovery::UdpEndpoint> endpoint,-                    discovery::IpAddress gateway)-    {-      mpController->mpSessionController->sawAudioEndpointCallback(-        peerId, endpoint, gateway);-    }--    Controller* mpController;-  };--  struct SessionMembershipCallback-  {-    void operator()() { mpController->mpSessionController->sessionMembershipCallback(); }--    Controller* mpController;-  };-   struct SessionPeerCounter   {     SessionPeerCounter(Controller& controller, PeerCountCallback callback)@@ -702,22 +686,12 @@     template <typename Peer, typename Handler>     void operator()(Peer peer, Handler handler)     {-      mpController->mpSessionController->measurePeerCallback(-        std::move(peer), std::move(handler));-    }--    Controller* mpController;-  };--  template <typename Peer, typename Handler>-  void measurePeer(Peer peer, Handler handler)-  {-    mDiscovery.withGateways(-      [peer, handler](auto begin, const auto end)-      {+      using It = typename Discovery::ServicePeerGateways::GatewayMap::iterator;+      using ValueType = typename Discovery::ServicePeerGateways::GatewayMap::value_type;+      mController.mDiscovery.withGateways([peer, handler](It begin, const It end) {         const auto addr = peer.second;-        const auto it =-          std::find_if(begin, end, [&addr](const auto& vt) { return vt.first == addr; });+        const auto it = std::find_if(+          begin, end, [&addr](const ValueType& vt) { return vt.first == addr; });         if (it != end)         {           it->second->measurePeer(std::move(peer.first), std::move(handler));@@ -729,54 +703,27 @@           handler(GhostXForm{});         }       });-  }--  struct JoinSessionCallback-  {-    void operator()(Session session)-    {-      mpController->mpSessionController->joinSessionCallback(std::move(session));     } -    Controller* mpController;+    Controller& mController;   }; -  void shutdown()+  struct JoinSessionCallback   {-    if (mIoStopped)+    void operator()(Session session)     {-      return;+      mController.joinSession(std::move(session));     } -    std::mutex mutex;-    std::condition_variable condition;--    this->mIo->async(-      [this, &mutex, &condition]()-      {-        mRtClientStateSetter.stop();--        mEnabled = false;-        mDiscovery.enable(false);--        std::unique_lock<std::mutex> lock(mutex);-        mIoStopped = true;-        condition.notify_one();-      });--    std::unique_lock<std::mutex> lock(mutex);-    condition.wait(lock, [&]() { return mIoStopped.load(); });--    this->mIo->stop();-  }+    Controller& mController;+  };    using IoType = typename util::Injected<IoContext>::type;    using ControllerPeers = Peers<IoType&,-                                SessionMembershipCallback,-                                SessionTimelineCallback,-                                SessionStartStopStateCallback,-                                SawAudioEndpointCallback>;+    std::reference_wrapper<SessionPeerCounter>,+    SessionTimelineCallback,+    SessionStartStopStateCallback>;    using ControllerGateway =     Gateway<typename ControllerPeers::GatewayObserver, Clock, IoType&>;@@ -785,24 +732,15 @@   struct GatewayFactory   {     GatewayPtr operator()(std::pair<NodeState, GhostXForm> state,-                          util::Injected<IoType&> io,-                          const discovery::IpAddress& addr)-    {-      return GatewayPtr{new ControllerGateway{-        std::move(io),-        addr,-        util::injectVal(makeGatewayObserver(mpController->mPeers, addr)),-        std::move(state.first),-        std::move(state.second),-        mpController->mClock}};-    }--    void gatewaysChanged()+      util::Injected<IoType&> io,+      const discovery::IpAddress& addr)     {-      mpController->mpSessionController->gatewaysChangedCallback();+      return GatewayPtr{new ControllerGateway{std::move(io), addr,+        util::injectVal(makeGatewayObserver(mController.mPeers, addr)),+        std::move(state.first), std::move(state.second), mController.mClock}};     } -    Controller* mpController;+    Controller& mController;   };    struct UdpSendExceptionHandler@@ -811,9 +749,9 @@      void operator()(const Exception exception)     {-      mpController->mIo->async(-        [this, exception]-        { mpController->mDiscovery.repairGateway(exception.interfaceAddr); });+      mpController->mIo->async([this, exception] {+        mpController->mDiscovery.repairGateway(exception.interfaceAddr);+      });     }      Controller* mpController;@@ -834,8 +772,6 @@   mutable RtClientState mRtClientState;   std::atomic<bool> mHasPendingRtClientStates; -  SessionController* mpSessionController;-   SessionPeerCounter mSessionPeerCounter;    std::atomic<bool> mEnabled;@@ -843,23 +779,22 @@   std::atomic<bool> mStartStopSyncEnabled;    util::Injected<IoContext> mIo;-  std::atomic<bool> mIoStopped{false}; +  RtClientStateSetter mRtClientStateSetter;+   ControllerPeers mPeers;    using ControllerSessions = Sessions<ControllerPeers&,-                                      MeasurePeer,-                                      JoinSessionCallback,-                                      typename util::Injected<IoContext>::type&,-                                      Clock>;+    MeasurePeer,+    JoinSessionCallback,+    typename util::Injected<IoContext>::type&,+    Clock>;   ControllerSessions mSessions;    using Discovery = discovery::Service<std::pair<NodeState, GhostXForm>,-                                       typename util::Injected<GatewayFactory>::type,-                                       typename util::Injected<IoContext>::type&>;+    GatewayFactory,+    typename util::Injected<IoContext>::type&>;   Discovery mDiscovery;--  RtClientStateSetter mRtClientStateSetter; };  } // namespace link
− link/include/ableton/link/EndpointV4.hpp
@@ -1,75 +0,0 @@-/* Copyright 2016, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <cassert>--namespace ableton-{-namespace link-{--template <std::int32_t Key = 'mep4'>-struct EndpointV4-{-  static constexpr std::int32_t key = Key;--  // Model the NetworkByteStreamSerializable concept-  friend std::uint32_t sizeInByteStream(const EndpointV4<Key> mep)-  {-    if (mep.ep.address().is_v6())-    {-      return 0;-    }-    return discovery::sizeInByteStream(-             static_cast<std::uint32_t>(mep.ep.address().to_v4().to_uint()))-           + discovery::sizeInByteStream(mep.ep.port());-  }--  template <typename It>-  friend It toNetworkByteStream(const EndpointV4<Key> mep, It out)-  {-    assert(mep.ep.address().is_v4());-    return discovery::toNetworkByteStream(-      mep.ep.port(),-      discovery::toNetworkByteStream(-        static_cast<std::uint32_t>(mep.ep.address().to_v4().to_uint()), std::move(out)));-  }--  template <typename It>-  static std::pair<EndpointV4<Key>, It> fromNetworkByteStream(It begin, It end)-  {-    using namespace std;-    auto addrRes =-      discovery::Deserialize<std::uint32_t>::fromNetworkByteStream(std::move(begin), end);-    auto portRes = discovery::Deserialize<std::uint16_t>::fromNetworkByteStream(-      std::move(addrRes.second), end);-    return make_pair(EndpointV4<Key>{{discovery::IpAddressV4{std::move(addrRes.first)},-                                      std::move(portRes.first)}},-                     std::move(portRes.second));-  }--  discovery::UdpEndpoint ep;-};--} // namespace link-} // namespace ableton
− link/include/ableton/link/EndpointV6.hpp
@@ -1,75 +0,0 @@-/* Copyright 2023, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/platforms/asio/AsioWrapper.hpp>-#include <cassert>--namespace ableton-{-namespace link-{--template <std::int32_t Key>-struct EndpointV6-{-  static constexpr std::int32_t key = Key;--  // Model the NetworkByteStreamSerializable concept-  friend std::uint32_t sizeInByteStream(const EndpointV6<Key> mep)-  {-    if (mep.ep.address().is_v4())-    {-      return 0;-    }-    return discovery::sizeInByteStream(mep.ep.address().to_v6().to_bytes())-           + discovery::sizeInByteStream(mep.ep.port());-  }--  template <typename It>-  friend It toNetworkByteStream(const EndpointV6<Key> mep, It out)-  {-    assert(mep.ep.address().is_v6());-    return discovery::toNetworkByteStream(-      mep.ep.port(),-      discovery::toNetworkByteStream(-        mep.ep.address().to_v6().to_bytes(), std::move(out)));-  }--  template <typename It>-  static std::pair<EndpointV6<Key>, It> fromNetworkByteStream(It begin, It end)-  {-    using namespace std;-    auto addrRes =-      discovery::Deserialize<discovery::IpAddressV6::bytes_type>::fromNetworkByteStream(-        std::move(begin), end);-    auto portRes = discovery::Deserialize<std::uint16_t>::fromNetworkByteStream(-      std::move(addrRes.second), end);-    return make_pair(EndpointV6<Key>{{discovery::IpAddressV6{std::move(addrRes.first)},-                                      std::move(portRes.first)}},-                     std::move(portRes.second));-  }--  discovery::UdpEndpoint ep;-};--} // namespace link-} // namespace ableton
link/include/ableton/link/Gateway.hpp view
@@ -23,8 +23,6 @@ #include <ableton/link/MeasurementService.hpp> #include <ableton/link/PeerState.hpp> -#include <optional>- namespace ableton { namespace link@@ -35,24 +33,21 @@ { public:   Gateway(util::Injected<IoContext> io,-          discovery::IpAddress addr,-          util::Injected<PeerObserver> observer,-          NodeState nodeState,-          GhostXForm ghostXForm,-          Clock clock,-          std::optional<discovery::UdpEndpoint> audioEndpoint = std::nullopt)+    discovery::IpAddress addr,+    util::Injected<PeerObserver> observer,+    NodeState nodeState,+    GhostXForm ghostXForm,+    Clock clock)     : mIo(std::move(io))     , mMeasurement(addr,-                   nodeState.sessionId,-                   std::move(ghostXForm),-                   std::move(clock),-                   util::injectRef(*mIo))-    , moAudioEndpoint(audioEndpoint)-    , mPeerGateway(discovery::makeGateway(-        util::injectRef(*mIo),+        nodeState.sessionId,+        std::move(ghostXForm),+        std::move(clock),+        util::injectRef(*mIo))+    , mPeerGateway(discovery::makeGateway(util::injectRef(*mIo),         std::move(addr),         std::move(observer),-        PeerState{std::move(nodeState), mMeasurement.endpoint(), moAudioEndpoint}))+        PeerState{std::move(nodeState), mMeasurement.endpoint()}))   {   } @@ -62,7 +57,6 @@   Gateway(Gateway&& rhs)     : mIo(std::move(rhs.mIo))     , mMeasurement(std::move(rhs.mMeasurement))-    , moAudioEndpoint(std::move(rhs.moAudioEndpoint))     , mPeerGateway(std::move(rhs.mPeerGateway))   {   }@@ -71,7 +65,6 @@   {     mIo = std::move(rhs.mIo);     mMeasurement = std::move(rhs.mMeasurement);-    moAudioEndpoint = std::move(rhs.moAudioEndpoint);     mPeerGateway = std::move(rhs.mPeerGateway);     return *this;   }@@ -79,13 +72,7 @@   void updateNodeState(std::pair<NodeState, GhostXForm> state)   {     mMeasurement.updateNodeState(state.first.sessionId, state.second);-    mPeerGateway.updateState(-      PeerState{std::move(state.first), mMeasurement.endpoint(), moAudioEndpoint});-  }--  void updateAudioEndpoint(std::optional<discovery::UdpEndpoint> audioEndpoint)-  {-    moAudioEndpoint = audioEndpoint;+    mPeerGateway.updateState(PeerState{std::move(state.first), mMeasurement.endpoint()});   }    template <typename Handler>@@ -97,7 +84,6 @@ private:   util::Injected<IoContext> mIo;   MeasurementService<Clock, typename util::Injected<IoContext>::type&> mMeasurement;-  std::optional<discovery::UdpEndpoint> moAudioEndpoint;   discovery::Gateway<PeerObserver, PeerState, typename util::Injected<IoContext>::type&>     mPeerGateway; };
link/include/ableton/link/Measurement.hpp view
@@ -39,25 +39,20 @@ {   using Callback = std::function<void(std::vector<double>&)>;   using Micros = std::chrono::microseconds;-  using Socket =-    typename util::Injected<IoContext>::type::template Socket<v1::kMaxMessageSize>;    static const std::size_t kNumberDataPoints = 100;   static const std::size_t kNumberMeasurements = 5;    Measurement(const PeerState& state,-              Callback callback,-              discovery::IpAddress address,-              Clock clock,-              util::Injected<IoContext> io,-              Socket& socket)-    : mpImpl(std::make_shared<Impl>(std::move(state),-                                    std::move(callback),-                                    std::move(address),-                                    std::move(clock),-                                    std::move(io),-                                    socket))+    Callback callback,+    discovery::IpAddress address,+    Clock clock,+    util::Injected<IoContext> io)+    : mIo(std::move(io))+    , mpImpl(std::make_shared<Impl>(+        std::move(state), std::move(callback), std::move(address), std::move(clock), mIo))   {+    mpImpl->listen();   }    Measurement(const Measurement&) = delete;@@ -65,44 +60,36 @@   Measurement(const Measurement&&) = delete;   Measurement& operator=(Measurement&&) = delete; -  template <typename It>-  void operator()(const discovery::UdpEndpoint& from,-                  const It messageBegin,-                  const It messageEnd)-  {-    (*mpImpl)(from, messageBegin, messageEnd);-  }-   struct Impl : std::enable_shared_from_this<Impl>   {+    using Socket =+      typename util::Injected<IoContext>::type::template Socket<v1::kMaxMessageSize>;     using Timer = typename util::Injected<IoContext>::type::Timer;     using Log = typename util::Injected<IoContext>::type::Log;      Impl(const PeerState& state,-         Callback callback,-         discovery::IpAddress address,-         Clock clock,-         util::Injected<IoContext> io,-         Socket& socket)-      : mIo(std::move(io))-      , mSocket(socket)+      Callback callback,+      discovery::IpAddress address,+      Clock clock,+      util::Injected<IoContext> io)+      : mSocket(io->template openUnicastSocket<v1::kMaxMessageSize>(address))       , mSessionId(state.nodeState.sessionId)       , mCallback(std::move(callback))       , mClock(std::move(clock))-      , mTimer(mIo->makeTimer())+      , mTimer(io->makeTimer())       , mMeasurementsStarted(0)-      , mLog(channel(mIo->log(), "Measurement on gateway@" + address.to_string()))+      , mLog(channel(io->log(), "Measurement on gateway@" + address.to_string()))       , mSuccess(false)     {-      if (state.measurementEndpoint.address().is_v4())+      if (state.endpoint.address().is_v4())       {-        mEndpoint = state.measurementEndpoint;+        mEndpoint = state.endpoint;       }       else       {-        auto v6Address = state.measurementEndpoint.address().to_v6();+        auto v6Address = state.endpoint.address().to_v6();         v6Address.scope_id(address.to_v6().scope_id());-        mEndpoint = {v6Address, state.measurementEndpoint.port()};+        mEndpoint = {v6Address, state.endpoint.port()};       }        const auto ht = HostTime{mClock.micros()};@@ -114,31 +101,33 @@     {       mTimer.cancel();       mTimer.expires_from_now(std::chrono::milliseconds(50));-      mTimer.async_wait(-        [this](const typename Timer::ErrorCode e)+      mTimer.async_wait([this](const typename Timer::ErrorCode e) {+        if (!e)         {-          if (!e)+          if (mMeasurementsStarted < kNumberMeasurements)           {-            if (mMeasurementsStarted < kNumberMeasurements)-            {-              const auto ht = HostTime{mClock.micros()};-              sendPing(mEndpoint, discovery::makePayload(ht));-              ++mMeasurementsStarted;-              resetTimer();-            }-            else-            {-              fail();-            }+            const auto ht = HostTime{mClock.micros()};+            sendPing(mEndpoint, discovery::makePayload(ht));+            ++mMeasurementsStarted;+            resetTimer();           }-        });+          else+          {+            fail();+          }+        }+      });     } +    void listen()+    {+      mSocket.receive(util::makeAsyncSafe(this->shared_from_this()));+    }+     // Operator to handle incoming messages on the interface     template <typename It>-    void operator()(const discovery::UdpEndpoint& from,-                    const It messageBegin,-                    const It messageEnd)+    void operator()(+      const discovery::UdpEndpoint& from, const It messageBegin, const It messageEnd)     {       using namespace std;       const auto result = v1::parseMessageHeader(messageBegin, messageEnd);@@ -158,8 +147,7 @@         try         {           discovery::parsePayload<SessionMembership, GHostTime, PrevGHostTime, HostTime>(-            payloadBegin,-            messageEnd,+            payloadBegin, messageEnd,             [&sessionId](const SessionMembership& sms) { sessionId = sms.sessionId; },             [&ghostTime](GHostTime gt) { ghostTime = std::move(gt.time); },             [&prevGHostTime](PrevGHostTime gt) { prevGHostTime = std::move(gt.time); },@@ -168,6 +156,7 @@         catch (const std::runtime_error& err)         {           warning(mLog) << "Failed parsing payload, caught exception: " << err.what();+          listen();           return;         } @@ -179,7 +168,9 @@             discovery::makePayload(HostTime{hostTime}, PrevGHostTime{ghostTime});            sendPing(from, payload);+          listen(); +           if (ghostTime != Micros{0} && prevHostTime != Micros{0})           {             mData.push_back(@@ -211,6 +202,7 @@       else       {         debug(mLog) << "Received invalid message from " << from;+        listen();       }     } @@ -238,34 +230,17 @@       mTimer.cancel();       mSuccess = true;       debug(mLog) << "Measuring " << mEndpoint << " done.";-      std::weak_ptr<Impl> pHandle = this->shared_from_this();-      mIo->async(-        [pHandle]()-        {-          if (auto pLocked = pHandle.lock())-          {-            pLocked->mCallback(pLocked->mData);-          }-        });+      mCallback(mData);     }      void fail()     {+      mData.clear();       debug(mLog) << "Measuring " << mEndpoint << " failed.";-      std::weak_ptr<Impl> pHandle = this->shared_from_this();-      mIo->async(-        [pHandle]()-        {-          if (auto pLocked = pHandle.lock())-          {-            pLocked->mData.clear();-            pLocked->mCallback(pLocked->mData);-          }-        });+      mCallback(mData);     } -    util::Injected<IoContext> mIo;-    Socket& mSocket;+    Socket mSocket;     SessionId mSessionId;     discovery::UdpEndpoint mEndpoint;     std::vector<double> mData;@@ -277,6 +252,7 @@     bool mSuccess;   }; +  util::Injected<IoContext> mIo;   std::shared_ptr<Impl> mpImpl; }; 
+ link/include/ableton/link/MeasurementEndpointV4.hpp view
@@ -0,0 +1,75 @@+/* Copyright 2016, Ableton AG, Berlin. All rights reserved.+ *+ *  This program is free software: you can redistribute it and/or modify+ *  it under the terms of the GNU General Public License as published by+ *  the Free Software Foundation, either version 2 of the License, or+ *  (at your option) any later version.+ *+ *  This program is distributed in the hope that it will be useful,+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ *  GNU General Public License for more details.+ *+ *  You should have received a copy of the GNU General Public License+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.+ *+ *  If you would like to incorporate Link into a proprietary software application,+ *  please contact <link-devs@ableton.com>.+ */++#pragma once++#include <ableton/discovery/AsioTypes.hpp>+#include <ableton/discovery/NetworkByteStreamSerializable.hpp>+#include <cassert>++namespace ableton+{+namespace link+{++struct MeasurementEndpointV4+{+  static const std::int32_t key = 'mep4';+  static_assert(key == 0x6d657034, "Unexpected byte order");++  // Model the NetworkByteStreamSerializable concept+  friend std::uint32_t sizeInByteStream(const MeasurementEndpointV4 mep)+  {+    if (mep.ep.address().is_v6())+    {+      return 0;+    }+    return discovery::sizeInByteStream(+             static_cast<std::uint32_t>(mep.ep.address().to_v4().to_ulong()))+           + discovery::sizeInByteStream(mep.ep.port());+  }++  template <typename It>+  friend It toNetworkByteStream(const MeasurementEndpointV4 mep, It out)+  {+    assert(mep.ep.address().is_v4());+    return discovery::toNetworkByteStream(mep.ep.port(),+      discovery::toNetworkByteStream(+        static_cast<std::uint32_t>(mep.ep.address().to_v4().to_ulong()), std::move(out)));+  }++  template <typename It>+  static std::pair<MeasurementEndpointV4, It> fromNetworkByteStream(It begin, It end)+  {+    using namespace std;+    auto addrRes =+      discovery::Deserialize<std::uint32_t>::fromNetworkByteStream(std::move(begin), end);+    auto portRes = discovery::Deserialize<std::uint16_t>::fromNetworkByteStream(+      std::move(addrRes.second), end);+    return make_pair(+      MeasurementEndpointV4{+        {discovery::IpAddressV4{std::move(addrRes.first)}, std::move(portRes.first)}},+      std::move(portRes.second));+  }++  discovery::UdpEndpoint ep;+};++} // namespace link+} // namespace ableton
+ link/include/ableton/link/MeasurementEndpointV6.hpp view
@@ -0,0 +1,75 @@+/* Copyright 2023, Ableton AG, Berlin. All rights reserved.+ *+ *  This program is free software: you can redistribute it and/or modify+ *  it under the terms of the GNU General Public License as published by+ *  the Free Software Foundation, either version 2 of the License, or+ *  (at your option) any later version.+ *+ *  This program is distributed in the hope that it will be useful,+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ *  GNU General Public License for more details.+ *+ *  You should have received a copy of the GNU General Public License+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.+ *+ *  If you would like to incorporate Link into a proprietary software application,+ *  please contact <link-devs@ableton.com>.+ */++#pragma once++#include <ableton/discovery/NetworkByteStreamSerializable.hpp>+#include <ableton/platforms/asio/AsioWrapper.hpp>+#include <cassert>++namespace ableton+{+namespace link+{++struct MeasurementEndpointV6+{+  static const std::int32_t key = 'mep6';+  static_assert(key == 0x6d657036, "Unexpected byte order");++  // Model the NetworkByteStreamSerializable concept+  friend std::uint32_t sizeInByteStream(const MeasurementEndpointV6 mep)+  {+    if (mep.ep.address().is_v4())+    {+      return 0;+    }+    return discovery::sizeInByteStream(mep.ep.address().to_v6().to_bytes())+           + discovery::sizeInByteStream(mep.ep.port());+  }++  template <typename It>+  friend It toNetworkByteStream(const MeasurementEndpointV6 mep, It out)+  {+    assert(mep.ep.address().is_v6());+    return discovery::toNetworkByteStream(+      mep.ep.port(), discovery::toNetworkByteStream(+                       mep.ep.address().to_v6().to_bytes(), std::move(out)));+  }++  template <typename It>+  static std::pair<MeasurementEndpointV6, It> fromNetworkByteStream(It begin, It end)+  {+    using namespace std;+    auto addrRes =+      discovery::Deserialize<discovery::IpAddressV6::bytes_type>::fromNetworkByteStream(+        std::move(begin), end);+    auto portRes = discovery::Deserialize<std::uint16_t>::fromNetworkByteStream(+      std::move(addrRes.second), end);+    return make_pair(+      MeasurementEndpointV6{+        {discovery::IpAddressV6{std::move(addrRes.first)}, std::move(portRes.first)}},+      std::move(portRes.second));+  }++  discovery::UdpEndpoint ep;+};++} // namespace link+} // namespace ableton
link/include/ableton/link/MeasurementService.hpp view
@@ -39,19 +39,22 @@ class MeasurementService { public:-  using IoType = typename util::Injected<IoContext>::type;-  using MeasurementInstance = Measurement<Clock, IoType&>;+  using IoType = util::Injected<IoContext>;+  using MeasurementInstance = Measurement<Clock, IoContext>;    MeasurementService(discovery::IpAddress address,-                     SessionId sessionId,-                     GhostXForm ghostXForm,-                     Clock clock,-                     util::Injected<IoContext> io)+    SessionId sessionId,+    GhostXForm ghostXForm,+    Clock clock,+    IoType io)     : mClock(std::move(clock))-    , mpImpl(std::make_shared<Impl>(-        address, std::move(sessionId), std::move(ghostXForm), mClock, std::move(io)))+    , mIo(std::move(io))+    , mPingResponder(std::move(address),+        std::move(sessionId),+        std::move(ghostXForm),+        mClock,+        util::injectRef(*mIo))   {-    mpImpl->listen();   }    MeasurementService(const MeasurementService&) = delete;@@ -59,10 +62,13 @@    void updateNodeState(const SessionId& sessionId, const GhostXForm& xform)   {-    mpImpl->updateNodeState(sessionId, xform);+    mPingResponder.updateNodeState(sessionId, xform);   } -  discovery::UdpEndpoint endpoint() const { return mpImpl->socket().endpoint(); }+  discovery::UdpEndpoint endpoint() const+  {+    return mPingResponder.endpoint();+  }    // Measure the peer and invoke the handler with a GhostXForm   template <typename Handler>@@ -71,83 +77,28 @@     using namespace std;      const auto nodeId = state.nodeState.nodeId;-    auto addr = mpImpl->socket().endpoint().address();-    auto callback = CompletionCallback<Handler>{mpImpl, nodeId, handler};+    auto addr = mPingResponder.endpoint().address();+    auto callback = CompletionCallback<Handler>{*this, nodeId, handler};      try     {-      mpImpl->mMeasurementMap[nodeId] =-        std::make_unique<MeasurementInstance>(state,-                                              std::move(callback),-                                              std::move(addr),-                                              mClock,-                                              util::injectRef(*(mpImpl->mIo)),-                                              mpImpl->socket());+      mMeasurementMap[nodeId] =+        std::unique_ptr<MeasurementInstance>(new MeasurementInstance{+          state, std::move(callback), std::move(addr), mClock, mIo});     }     catch (const runtime_error& err)     {-      info(mpImpl->mIo->log()) << "gateway@" + addr.to_string()-                               << " Failed to measure. Reason: " << err.what();+      info(mIo->log()) << "gateway@" + addr.to_string()+                       << " Failed to measure. Reason: " << err.what();       handler(GhostXForm{});     }   } -  struct Impl : std::enable_shared_from_this<Impl>-  {-    using Socket = typename IoType::template Socket<v1::kMaxMessageSize>;--    Impl(discovery::IpAddress address,-         SessionId sessionId,-         GhostXForm ghostXForm,-         Clock clock,-         util::Injected<IoContext> io)-      : mIo(std::move(io))-      , mSocket((*mIo).template openUnicastSocket<v1::kMaxMessageSize>(address))-      , mPingResponder(mSocket,-                       std::move(sessionId),-                       std::move(ghostXForm),-                       clock,-                       util::injectRef(*mIo))-    {-    }--    void updateNodeState(const SessionId& sessionId, const GhostXForm& xform)-    {-      mPingResponder.updateNodeState(sessionId, xform);-    }--    template <typename It>-    void operator()(const discovery::UdpEndpoint& from,-                    const It messageBegin,-                    const It messageEnd)-    {-      mPingResponder(from, messageBegin, messageEnd);--      for (auto it = mMeasurementMap.begin(); it != mMeasurementMap.end(); ++it)-      {-        (*(it->second))(from, messageBegin, messageEnd);-      }--      listen();-    }--    void listen() { mSocket.receive(util::makeAsyncSafe(this->shared_from_this())); }--    Socket& socket() { return mSocket; }--    using MeasurementMap = std::map<NodeId, std::unique_ptr<MeasurementInstance>>;--    util::Injected<IoContext> mIo;-    Socket mSocket;-    PingResponder<Clock, IoType&> mPingResponder;-    MeasurementMap mMeasurementMap;-  };- private:   template <typename Handler>   struct CompletionCallback   {-    void operator()(std::vector<double> data)+    void operator()(std::vector<double>& data)     {       using namespace std;       using std::chrono::microseconds;@@ -158,7 +109,7 @@       // gone by the time the block gets executed.       auto nodeId = mNodeId;       auto handler = mHandler;-      auto& measurementMap = mpImpl->mMeasurementMap;+      auto& measurementMap = mMeasurementService.mMeasurementMap;       const auto it = measurementMap.find(nodeId);       if (it != measurementMap.end())       {@@ -174,7 +125,7 @@       }     } -    std::shared_ptr<Impl> mpImpl;+    MeasurementService& mMeasurementService;     NodeId mNodeId;     Handler mHandler;   };@@ -182,9 +133,11 @@   // Make sure the measurement map outlives the IoContext so that the rest of   // the members are guaranteed to be valid when any final handlers   // are begin run.-+  using MeasurementMap = std::map<NodeId, std::unique_ptr<MeasurementInstance>>;+  MeasurementMap mMeasurementMap;   Clock mClock;-  std::shared_ptr<Impl> mpImpl;+  IoType mIo;+  PingResponder<Clock, IoContext> mPingResponder; };  } // namespace link
link/include/ableton/link/NodeId.hpp view
@@ -23,7 +23,6 @@ #include <algorithm> #include <array> #include <cstdint>-#include <iomanip> #include <string>  namespace ableton@@ -56,18 +55,7 @@    friend std::ostream& operator<<(std::ostream& stream, const NodeId& id)   {-    const auto flags = stream.flags();-    const auto fill = stream.fill();--    stream << "0x" << std::hex << std::setfill('0');-    for (const auto byte : id)-    {-      stream << std::setw(2) << static_cast<int>(byte);-    }--    stream.flags(flags);-    stream.fill(fill);-    return stream;+    return stream << std::string{id.cbegin(), id.cend()};   }    template <typename It>
link/include/ableton/link/NodeState.hpp view
@@ -35,7 +35,10 @@   using Payload =     decltype(discovery::makePayload(Timeline{}, SessionMembership{}, StartStopState{})); -  NodeId ident() const { return nodeId; }+  NodeId ident() const+  {+    return nodeId;+  }    friend bool operator==(const NodeState& lhs, const NodeState& rhs)   {@@ -54,14 +57,13 @@   {     using namespace std;     auto nodeState = NodeState{std::move(nodeId), {}, {}, {}};-    discovery::parsePayload<Timeline, SessionMembership, StartStopState>(-      std::move(begin),-      std::move(end),-      [&nodeState](Timeline tl) { nodeState.timeline = std::move(tl); },-      [&nodeState](SessionMembership membership)-      { nodeState.sessionId = std::move(membership.sessionId); },-      [&nodeState](StartStopState ststst)-      { nodeState.startStopState = std::move(ststst); });+    discovery::parsePayload<Timeline, SessionMembership, StartStopState>(std::move(begin),+      std::move(end), [&nodeState](Timeline tl) { nodeState.timeline = std::move(tl); },+      [&nodeState](SessionMembership membership) {+        nodeState.sessionId = std::move(membership.sessionId);+      },+      [&nodeState](+        StartStopState ststst) { nodeState.startStopState = std::move(ststst); });     return nodeState;   } 
+ link/include/ableton/link/Optional.hpp view
@@ -0,0 +1,97 @@+/* Copyright 2017, Ableton AG, Berlin. All rights reserved.+ *+ *  This program is free software: you can redistribute it and/or modify+ *  it under the terms of the GNU General Public License as published by+ *  the Free Software Foundation, either version 2 of the License, or+ *  (at your option) any later version.+ *+ *  This program is distributed in the hope that it will be useful,+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ *  GNU General Public License for more details.+ *+ *  You should have received a copy of the GNU General Public License+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.+ *+ *  If you would like to incorporate Link into a proprietary software application,+ *  please contact <link-devs@ableton.com>.+ */++#pragma once++#include <cassert>+#include <utility>++namespace ableton+{+namespace link+{++// Subset of the C++ 17 std::optional API. T has to be default constructible.+template <typename T>+struct Optional+{+  Optional()+    : mHasValue(false)+  {+  }++  explicit Optional(T value)+    : mValue(std::move(value))+    , mHasValue(true)+  {+  }++  Optional(const Optional&) = default;++  Optional(Optional&& other)+    : mValue(std::move(other.mValue))+    , mHasValue(other.mHasValue)+  {+  }++  Optional& operator=(const Optional&) = default;++  Optional& operator=(Optional&& other)+  {+    mValue = std::move(other.mValue);+    mHasValue = other.mHasValue;+    return *this;+  }++  explicit operator bool() const+  {+    return mHasValue;+  }++  const T& operator*() const+  {+    assert(mHasValue);+    return mValue;+  }++  T& operator*()+  {+    assert(mHasValue);+    return mValue;+  }++  const T* operator->() const+  {+    assert(mHasValue);+    return &mValue;+  }++  T* operator->()+  {+    assert(mHasValue);+    return &mValue;+  }++private:+  T mValue;+  bool mHasValue;+};++} // namespace link+} // namespace ableton
link/include/ableton/link/PeerState.hpp view
@@ -20,12 +20,10 @@ #pragma once  #include <ableton/discovery/Payload.hpp>-#include <ableton/link/EndpointV4.hpp>-#include <ableton/link/EndpointV6.hpp>+#include <ableton/link/MeasurementEndpointV4.hpp>+#include <ableton/link/MeasurementEndpointV6.hpp> #include <ableton/link/NodeState.hpp> -#include <optional>- namespace ableton { namespace link@@ -37,96 +35,61 @@  struct PeerState {-  static constexpr std::int32_t kMep4Key = 'mep4';-  using MeasurementEndpointV4 = EndpointV4<kMep4Key>;-  static_assert(MeasurementEndpointV4::key == 0x6d657034, "Unexpected byte order");--  static constexpr std::int32_t kMep6Key = 'mep6';-  using MeasurementEndpointV6 = EndpointV6<kMep6Key>;-  static_assert(MeasurementEndpointV6::key == 0x6d657036, "Unexpected byte order");--  static constexpr std::int32_t kAep4Key = 'aep4';-  using AudioEndpointV4 = EndpointV4<kAep4Key>;-  static_assert(AudioEndpointV4::key == 0x61657034, "Unexpected byte order");--  static constexpr std::int32_t kAep6Key = 'aep6';-  using AudioEndpointV6 = EndpointV6<kAep6Key>;-  static_assert(AudioEndpointV6::key == 0x61657036, "Unexpected byte order");-   using IdType = NodeId; -  IdType ident() const { return nodeState.ident(); }+  IdType ident() const+  {+    return nodeState.ident();+  } -  SessionId sessionId() const { return nodeState.sessionId; }+  SessionId sessionId() const+  {+    return nodeState.sessionId;+  } -  Timeline timeline() const { return nodeState.timeline; }+  Timeline timeline() const+  {+    return nodeState.timeline;+  } -  StartStopState startStopState() const { return nodeState.startStopState; }+  StartStopState startStopState() const+  {+    return nodeState.startStopState;+  }    friend bool operator==(const PeerState& lhs, const PeerState& rhs)   {-    return lhs.nodeState == rhs.nodeState-           && lhs.measurementEndpoint == rhs.measurementEndpoint-           && lhs.audioEndpoint == rhs.audioEndpoint;+    return lhs.nodeState == rhs.nodeState && lhs.endpoint == rhs.endpoint;   } -  friend auto toPayload(const PeerState& state)-    -> decltype(std::declval<NodeState::Payload>()-                + discovery::makePayload(MeasurementEndpointV4{{}})-                + discovery::makePayload(MeasurementEndpointV6{{}})-                + discovery::makePayload(AudioEndpointV4{{}})-                + discovery::makePayload(AudioEndpointV6{{}}))+  friend auto toPayload(const PeerState& state) -> decltype(+    std::declval<NodeState::Payload>() + discovery::makePayload(MeasurementEndpointV4{{}})+    + discovery::makePayload(MeasurementEndpointV6{{}}))   {     // This implements a switch if either an IPv4 or IPv6 endpoint is serialized.     // MeasurementEndpoints that contain an endpoint that does not match the IP protocol     // version return a sizeInByteStream() of zero and won't be serialized.     return toPayload(state.nodeState)-           + discovery::makePayload(MeasurementEndpointV4{state.measurementEndpoint})-           + discovery::makePayload(MeasurementEndpointV6{state.measurementEndpoint})-           + discovery::makePayload(AudioEndpointV4{-             state.audioEndpoint-               ? *state.audioEndpoint-               : discovery::UdpEndpoint{discovery::makeAddress("::"), {}}})-           + discovery::makePayload(AudioEndpointV6{-             state.audioEndpoint-               ? *state.audioEndpoint-               : discovery::UdpEndpoint{discovery::makeAddress("0.0.0.0"), {}}--           });+           + discovery::makePayload(MeasurementEndpointV4{state.endpoint})+           + discovery::makePayload(MeasurementEndpointV6{state.endpoint});   }    template <typename It>   static PeerState fromPayload(NodeId id, It begin, It end)   {     using namespace std;-    auto peerState = PeerState{NodeState::fromPayload(std::move(id), begin, end), {}, {}};+    auto peerState = PeerState{NodeState::fromPayload(std::move(id), begin, end), {}}; -    discovery::parsePayload<MeasurementEndpointV4,-                            MeasurementEndpointV6,-                            AudioEndpointV4,-                            AudioEndpointV6>(-      std::move(begin),-      std::move(end),-      [&peerState](MeasurementEndpointV4 me4)-      { peerState.measurementEndpoint = std::move(me4.ep); },-      [&peerState](MeasurementEndpointV6 me6)-      { peerState.measurementEndpoint = std::move(me6.ep); },-      [&peerState](AudioEndpointV4 ae4)-      {-        peerState.audioEndpoint =-          std::optional<discovery::UdpEndpoint>(std::move(ae4.ep));-      },-      [&peerState](AudioEndpointV6 ae6)-      {-        peerState.audioEndpoint =-          std::optional<discovery::UdpEndpoint>(std::move(ae6.ep));-      });+    discovery::parsePayload<MeasurementEndpointV4, MeasurementEndpointV6>(+      std::move(begin), std::move(end),+      [&peerState](MeasurementEndpointV4 me4) { peerState.endpoint = std::move(me4.ep); },+      [&peerState](+        MeasurementEndpointV6 me6) { peerState.endpoint = std::move(me6.ep); });     return peerState;   }    NodeState nodeState;-  discovery::UdpEndpoint measurementEndpoint;-  std::optional<discovery::UdpEndpoint> audioEndpoint;+  discovery::UdpEndpoint endpoint; };  } // namespace link
link/include/ableton/link/Peers.hpp view
@@ -38,10 +38,9 @@ // whenever a new combination of these values is seen  template <typename IoContext,-          typename SessionMembershipCallback,-          typename SessionTimelineCallback,-          typename SessionStartStopStateCallback,-          typename AudioEndpointCallback>+  typename SessionMembershipCallback,+  typename SessionTimelineCallback,+  typename SessionStartStopStateCallback> class Peers {   // non-movable private implementation type@@ -51,15 +50,11 @@   using Peer = std::pair<PeerState, discovery::IpAddress>;    Peers(util::Injected<IoContext> io,-        SessionMembershipCallback membership,-        SessionTimelineCallback timeline,-        SessionStartStopStateCallback startStop,-        AudioEndpointCallback audioEndpoint)-    : mpImpl(std::make_shared<Impl>(std::move(io),-                                    std::move(membership),-                                    std::move(timeline),-                                    std::move(startStop),-                                    std::move(audioEndpoint)))+    SessionMembershipCallback membership,+    SessionTimelineCallback timeline,+    SessionStartStopStateCallback startStop)+    : mpImpl(std::make_shared<Impl>(+        std::move(io), std::move(membership), std::move(timeline), std::move(startStop)))   {   } @@ -80,10 +75,8 @@   {     using namespace std;     auto peerVec = sessionPeers(sid);-    auto last = unique(begin(peerVec),-                       end(peerVec),-                       [](const Peer& a, const Peer& b)-                       { return a.first.ident() == b.first.ident(); });+    auto last = unique(begin(peerVec), end(peerVec),+      [](const Peer& a, const Peer& b) { return a.first.ident() == b.first.ident(); });     return static_cast<size_t>(distance(begin(peerVec), last));   } @@ -113,7 +106,10 @@       remove_if(begin(peerVec), end(peerVec), SessionMemberPred{sid}), end(peerVec));   } -  void resetPeers() { mpImpl->mPeers.clear(); }+  void resetPeers()+  {+    mpImpl->mPeers.clear();+  }    // Observer type that monitors peer discovery on a particular   // gateway and relays the information to a Peers instance.@@ -151,21 +147,21 @@       auto pImpl = observer.mpImpl;       auto addr = observer.mAddr;       assert(pImpl);-      pImpl->sawPeerOnGateway(state, std::move(addr));+      pImpl->sawPeerOnGateway(std::move(state), std::move(addr));     }      friend void peerLeft(GatewayObserver& observer, const NodeId& id)     {       auto pImpl = observer.mpImpl;       auto addr = observer.mAddr;-      pImpl->peerLeftGateway(id, std::move(addr));+      pImpl->peerLeftGateway(std::move(id), std::move(addr));     }      friend void peerTimedOut(GatewayObserver& observer, const NodeId& id)     {       auto pImpl = observer.mpImpl;       auto addr = observer.mAddr;-      pImpl->peerLeftGateway(id, std::move(addr));+      pImpl->peerLeftGateway(std::move(id), std::move(addr));     }      std::shared_ptr<Impl> mpImpl;@@ -182,15 +178,13 @@   struct Impl   {     Impl(util::Injected<IoContext> io,-         SessionMembershipCallback membership,-         SessionTimelineCallback timeline,-         SessionStartStopStateCallback startStop,-         AudioEndpointCallback audioEndpointCallback)+      SessionMembershipCallback membership,+      SessionTimelineCallback timeline,+      SessionStartStopStateCallback startStop)       : mIo(std::move(io))       , mSessionMembershipCallback(std::move(membership))       , mSessionTimelineCallback(std::move(timeline))       , mSessionStartStopStateCallback(std::move(startStop))-      , mAudioEndpointCallback(std::move(audioEndpointCallback))     {     } @@ -206,7 +200,7 @@       bool isNewSessionStartStopState =         !sessionStartStopStateExists(peerSession, peerStartStopState); -      auto peer = make_pair(peerState, gatewayAddr);+      auto peer = make_pair(std::move(peerState), std::move(gatewayAddr));       const auto idRange = equal_range(begin(mPeers), end(mPeers), peer, PeerIdComp{});        bool didSessionMembershipChange = false;@@ -220,10 +214,9 @@       {         // We've seen this peer before... does it have a new session?         didSessionMembershipChange =-          all_of(idRange.first,-                 idRange.second,-                 [&peerSession](const Peer& test)-                 { return test.first.sessionId() != peerSession; });+          all_of(idRange.first, idRange.second, [&peerSession](const Peer& test) {+            return test.first.sessionId() != peerSession;+          });          // was it on this gateway?         const auto addrRange =@@ -260,19 +253,15 @@       {         mSessionMembershipCallback();       }--      mAudioEndpointCallback(peerState.ident(), peerState.audioEndpoint, gatewayAddr);     }      void peerLeftGateway(const NodeId& nodeId, const discovery::IpAddress& gatewayAddr)     {       using namespace std; -      auto it =-        find_if(begin(mPeers),-                end(mPeers),-                [&](const Peer& peer)-                { return peer.first.ident() == nodeId && peer.second == gatewayAddr; });+      auto it = find_if(begin(mPeers), end(mPeers), [&](const Peer& peer) {+        return peer.first.ident() == nodeId && peer.second == gatewayAddr;+      });        bool didSessionMembershipChange = false;       if (it != end(mPeers))@@ -291,11 +280,10 @@     {       using namespace std; -      mPeers.erase(remove_if(begin(mPeers),-                             end(mPeers),-                             [&gatewayAddr](const Peer& peer)-                             { return peer.second == gatewayAddr; }),-                   end(mPeers));+      mPeers.erase(+        remove_if(begin(mPeers), end(mPeers),+          [&gatewayAddr](const Peer& peer) { return peer.second == gatewayAddr; }),+        end(mPeers));        mSessionMembershipCallback();     }@@ -304,27 +292,23 @@     bool hasPeerWith(const SessionId& sessionId, Predicate predicate)     {       using namespace std;-      return find_if(-               begin(mPeers),-               end(mPeers),-               [&](const Peer& peer)-               { return peer.first.sessionId() == sessionId && predicate(peer.first); })-             != end(mPeers);+      return find_if(begin(mPeers), end(mPeers), [&](const Peer& peer) {+        return peer.first.sessionId() == sessionId && predicate(peer.first);+      }) != end(mPeers);     }      bool sessionTimelineExists(const SessionId& session, const Timeline& timeline)     {       return hasPeerWith(session,-                         [&](const PeerState& peerState)-                         { return peerState.timeline() == timeline; });+        [&](const PeerState& peerState) { return peerState.timeline() == timeline; });     } -    bool sessionStartStopStateExists(const SessionId& sessionId,-                                     const StartStopState& startStopState)+    bool sessionStartStopStateExists(+      const SessionId& sessionId, const StartStopState& startStopState)     {-      return hasPeerWith(sessionId,-                         [&](const PeerState& peerState)-                         { return peerState.startStopState() == startStopState; });+      return hasPeerWith(sessionId, [&](const PeerState& peerState) {+        return peerState.startStopState() == startStopState;+      });     }      struct PeerIdComp@@ -347,13 +331,15 @@     SessionMembershipCallback mSessionMembershipCallback;     SessionTimelineCallback mSessionTimelineCallback;     SessionStartStopStateCallback mSessionStartStopStateCallback;-    AudioEndpointCallback mAudioEndpointCallback;     std::vector<Peer> mPeers; // sorted by peerId, unique by (peerId, addr)   };    struct SessionMemberPred   {-    bool operator()(const Peer& peer) const { return peer.first.sessionId() == sid; }+    bool operator()(const Peer& peer) const+    {+      return peer.first.sessionId() == sid;+    }      const SessionId& sid;   };@@ -362,26 +348,20 @@ };  template <typename Io,-          typename SessionMembershipCallback,-          typename SessionTimelineCallback,-          typename SessionStartStopStateCallback,-          typename AudioEndpointCallback>+  typename SessionMembershipCallback,+  typename SessionTimelineCallback,+  typename SessionStartStopStateCallback> Peers<Io,-      SessionMembershipCallback,-      SessionTimelineCallback,-      SessionStartStopStateCallback,-      AudioEndpointCallback>+  SessionMembershipCallback,+  SessionTimelineCallback,+  SessionStartStopStateCallback> makePeers(util::Injected<Io> io,-          SessionMembershipCallback membershipCallback,-          SessionTimelineCallback timelineCallback,-          SessionStartStopStateCallback startStopStateCallback,-          AudioEndpointCallback audioEndpointCallback)+  SessionMembershipCallback membershipCallback,+  SessionTimelineCallback timelineCallback,+  SessionStartStopStateCallback startStopStateCallback) {-  return {std::move(io),-          std::move(membershipCallback),-          std::move(timelineCallback),-          std::move(startStopStateCallback),-          std::move(audioEndpointCallback)};+  return {std::move(io), std::move(membershipCallback), std::move(timelineCallback),+    std::move(startStopStateCallback)}; }  } // namespace link
link/include/ableton/link/Phase.hpp view
@@ -73,9 +73,8 @@ // time. The phase of the resulting beat value can be calculated with // phase(beats, quantum). The result will deviate by up to +- // (quantum/2) beats compared to the result of tl.toBeats(time).-inline Beats toPhaseEncodedBeats(const Timeline& tl,-                                 const std::chrono::microseconds time,-                                 const Beats quantum)+inline Beats toPhaseEncodedBeats(+  const Timeline& tl, const std::chrono::microseconds time, const Beats quantum) {   const auto beat = tl.toBeats(time);   return closestPhaseMatch(beat, beat - tl.beatOrigin, quantum);@@ -84,9 +83,8 @@ // The inverse of toPhaseEncodedBeats. Given a phase encoded beat // value from the given timeline and quantum, find the time value that // it maps to.-inline std::chrono::microseconds fromPhaseEncodedBeats(const Timeline& tl,-                                                       const Beats beat,-                                                       const Beats quantum)+inline std::chrono::microseconds fromPhaseEncodedBeats(+  const Timeline& tl, const Beats beat, const Beats quantum) {   const auto fromOrigin = beat - tl.beatOrigin;   const auto originOffset = fromOrigin - phase(fromOrigin, quantum);
link/include/ableton/link/PingResponder.hpp view
@@ -36,21 +36,23 @@ template <typename Clock, typename IoContext> class PingResponder {-  using IoType = typename util::Injected<IoContext>::type;-  using Socket = typename IoType::template Socket<v1::kMaxMessageSize>;+  using IoType = util::Injected<IoContext&>;+  using Socket = typename IoType::type::template Socket<v1::kMaxMessageSize>;  public:-  PingResponder(Socket& socket,-                SessionId sessionId,-                GhostXForm ghostXForm,-                Clock clock,-                util::Injected<IoContext> io)-    : mpImpl(std::make_shared<Impl>(socket,-                                    std::move(sessionId),-                                    std::move(ghostXForm),-                                    std::move(clock),-                                    std::move(io)))+  PingResponder(discovery::IpAddress address,+    SessionId sessionId,+    GhostXForm ghostXForm,+    Clock clock,+    IoType io)+    : mIo(io)+    , mpImpl(std::make_shared<Impl>(std::move(address),+        std::move(sessionId),+        std::move(ghostXForm),+        std::move(clock),+        std::move(io)))   {+    mpImpl->listen();   }    PingResponder(const PingResponder&) = delete;@@ -62,36 +64,42 @@     mpImpl->mGhostXForm = std::move(xform);   } -  discovery::UdpEndpoint endpoint() const { return mpImpl->mSocket.endpoint(); }--  discovery::IpAddress address() const { return endpoint().address(); }+  discovery::UdpEndpoint endpoint() const+  {+    return mpImpl->mSocket.endpoint();+  } -  Socket socket() const { return mpImpl->mSocket; }+  discovery::IpAddress address() const+  {+    return endpoint().address();+  } -  template <typename It>-  void operator()(const discovery::UdpEndpoint& from,-                  const It messageBegin,-                  const It messageEnd)+  Socket socket() const   {-    (*mpImpl)(from, messageBegin, messageEnd);+    return mpImpl->mSocket;   }  private:   struct Impl : std::enable_shared_from_this<Impl>   {-    Impl(Socket& socket,-         SessionId sessionId,-         GhostXForm ghostXForm,-         Clock clock,-         util::Injected<IoContext> io)+    Impl(discovery::IpAddress address,+      SessionId sessionId,+      GhostXForm ghostXForm,+      Clock clock,+      IoType io)       : mSessionId(std::move(sessionId))       , mGhostXForm(std::move(ghostXForm))       , mClock(std::move(clock))-      , mLog(channel(io->log(), "gateway@" + socket.endpoint().address().to_string()))-      , mSocket(socket)+      , mLog(channel(io->log(), "gateway@" + address.to_string()))+      , mSocket(io->template openUnicastSocket<v1::kMaxMessageSize>(address))     {     } +    void listen()+    {+      mSocket.receive(util::makeAsyncSafe(this->shared_from_this()));+    }+     // Operator to handle incoming messages on the interface     template <typename It>     void operator()(const discovery::UdpEndpoint& from, const It begin, const It end)@@ -124,6 +132,7 @@       {         info(mLog) << " Received invalid Message from " << from << ".";       }+      listen();     }      template <typename It>@@ -150,10 +159,11 @@     SessionId mSessionId;     GhostXForm mGhostXForm;     Clock mClock;-    typename IoType::Log mLog;-    Socket& mSocket;+    typename IoType::type::Log mLog;+    Socket mSocket;   }; +  IoType mIo;   std::shared_ptr<Impl> mpImpl; }; 
− link/include/ableton/link/SessionController.hpp
@@ -1,106 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/Controller.hpp>--#include <optional>--namespace ableton-{-namespace link-{--template <typename PeerCountCallback,-          typename TempoCallback,-          typename StartStopStateCallback,-          typename Clock,-          typename Random,-          typename IoContext>-class SessionController : public Controller<PeerCountCallback,-                                            TempoCallback,-                                            StartStopStateCallback,-                                            Clock,-                                            Random,-                                            IoContext,-                                            SessionController<PeerCountCallback,-                                                              TempoCallback,-                                                              StartStopStateCallback,-                                                              Clock,-                                                              Random,-                                                              IoContext>>-{-public:-  using LinkController = Controller<PeerCountCallback,-                                    TempoCallback,-                                    StartStopStateCallback,-                                    Clock,-                                    Random,-                                    IoContext,-                                    SessionController<PeerCountCallback,-                                                      TempoCallback,-                                                      StartStopStateCallback,-                                                      Clock,-                                                      Random,-                                                      IoContext>>;--  SessionController(Tempo tempo,-                    PeerCountCallback peerCallback,-                    TempoCallback tempoCallback,-                    StartStopStateCallback startStopStateCallback,-                    Clock clock)-    : LinkController(tempo, peerCallback, tempoCallback, startStopStateCallback, clock)-  {-    this->mRtClientStateSetter.start();-  }--  ~SessionController() { this->shutdown(); }--  void sessionMembershipCallback() { this->mSessionPeerCounter(); }--  void joinSessionCallback(const Session& session) { this->joinSession(session); }--  template <typename Peer, typename Handler>-  void measurePeerCallback(Peer peer, Handler handler)-  {-    this->measurePeer(std::move(peer), std::move(handler));-  }--  void updateDiscoveryCallback() { this->updateDiscovery(); }--  void gatewaysChangedCallback() {}--  void updateRtStatesCallback()-  {-    // Process the pending client states first to make sure we don't push one-    // after we have joined a running session when enabling-    this->mRtClientStateSetter.processPendingClientStates();-    this->mRtClientStateSetter.updateEnabled();-  }--  void sawAudioEndpointCallback(NodeId,-                                std::optional<discovery::UdpEndpoint>,-                                discovery::IpAddress)-  {-  }-};--} // namespace link-} // namespace ableton
link/include/ableton/link/SessionState.hpp view
@@ -19,21 +19,20 @@  #pragma once -#include <ableton/link/SessionId.hpp>+#include <ableton/link/Optional.hpp> #include <ableton/link/StartStopState.hpp> #include <ableton/link/Timeline.hpp>-#include <ableton/util/TripleBuffer.hpp>+#include <ableton/link/TripleBuffer.hpp> #include <mutex>-#include <optional>  namespace ableton { namespace link { -using OptionalTimeline = std::optional<Timeline>;-using OptionalStartStopState = std::optional<StartStopState>;-using OptionalClientStartStopState = std::optional<ClientStartStopState>;+using OptionalTimeline = Optional<Timeline>;+using OptionalStartStopState = Optional<StartStopState>;+using OptionalClientStartStopState = Optional<ClientStartStopState>;  struct SessionState {@@ -56,7 +55,6 @@   }    Timeline timeline;-  SessionId timelineSessionId;   ClientStartStopState startStopState; }; @@ -82,18 +80,20 @@     return mState;   } -  ClientState getRt() const { return mRtState.read(); }+  ClientState getRt() const+  {+    return mRtState.read();+  }  private:   mutable std::mutex mMutex;   ClientState mState;-  mutable util::TripleBuffer<ClientState> mRtState;+  mutable TripleBuffer<ClientState> mRtState; };  struct RtClientState {   Timeline timeline;-  SessionId timelineSessionId;   ClientStartStopState startStopState;   std::chrono::microseconds timelineTimestamp;   std::chrono::microseconds startStopStateTimestamp;@@ -108,33 +108,9 @@  struct ApiState {-  friend bool operator==(const ApiState& lhs, const ApiState& rhs)-  {-    return std::tie(lhs.timeline, lhs.timelineSessionId, lhs.startStopState)-           == std::tie(rhs.timeline, rhs.timelineSessionId, rhs.startStopState);-  }--  friend bool operator!=(const ApiState& lhs, const ApiState& rhs)-  {-    return !(lhs == rhs);-  }-   Timeline timeline;-  SessionId timelineSessionId;   ApiStartStopState startStopState; };  } // namespace link---namespace detail-{-template <typename SessionState>-const link::ApiState& linkApiState(const SessionState& sessionState)-{-  return sessionState.mState;-}--} // namespace detail- } // namespace ableton
link/include/ableton/link/Sessions.hpp view
@@ -42,21 +42,21 @@ };  template <typename Peers,-          typename MeasurePeer,-          typename JoinSessionCallback,-          typename IoContext,-          typename Clock>+  typename MeasurePeer,+  typename JoinSessionCallback,+  typename IoContext,+  typename Clock> class Sessions { public:   using Timer = typename util::Injected<IoContext>::type::Timer;    Sessions(Session init,-           util::Injected<Peers> peers,-           MeasurePeer measure,-           JoinSessionCallback join,-           util::Injected<IoContext> io,-           Clock clock)+    util::Injected<Peers> peers,+    MeasurePeer measure,+    JoinSessionCallback join,+    util::Injected<IoContext> io,+    Clock clock)     : mPeers(std::move(peers))     , mMeasure(std::move(measure))     , mCallback(std::move(join))@@ -73,7 +73,10 @@     mOtherSessions.clear();   } -  void resetTimeline(Timeline timeline) { mCurrent.timeline = std::move(timeline); }+  void resetTimeline(Timeline timeline)+  {+    mCurrent.timeline = std::move(timeline);+  }    // Consider the observed session/timeline pair and return a possibly   // new timeline that should be used going forward.@@ -114,10 +117,8 @@     if (!peers.empty())     {       // first criteria: always prefer the founding peer-      const auto it = find_if(begin(peers),-                              end(peers),-                              [&session](const Peer& peer)-                              { return session.sessionId == peer.first.ident(); });+      const auto it = find_if(begin(peers), end(peers),+        [&session](const Peer& peer) { return session.sessionId == peer.first.ident(); });       // TODO: second criteria should be degree. We don't have that       // represented yet so just use the first peer for now       auto peer = it == end(peers) ? peers.front() : *it;@@ -160,7 +161,7 @@         const auto ghostDiff = newGhost - curGhost;         if (ghostDiff > SESSION_EPS             || (std::abs(ghostDiff.count()) < SESSION_EPS.count()-                && id < mCurrent.sessionId))+                 && id < mCurrent.sessionId))         {           // The new session wins, switch over to it           auto current = mCurrent;@@ -184,15 +185,13 @@   {     // set a timer to re-measure the active session after a period     mTimer.expires_from_now(std::chrono::microseconds{30000000});-    mTimer.async_wait(-      [this](const typename Timer::ErrorCode e)+    mTimer.async_wait([this](const typename Timer::ErrorCode e) {+      if (!e)       {-        if (!e)-        {-          launchSessionMeasurement(mCurrent);-          scheduleRemeasurement();-        }-      });+        launchSessionMeasurement(mCurrent);+        scheduleRemeasurement();+      }+    });   }    void handleFailedMeasurement(const SessionId& id)@@ -281,10 +280,10 @@ };  template <typename Peers,-          typename MeasurePeer,-          typename JoinSessionCallback,-          typename IoContext,-          typename Clock>+  typename MeasurePeer,+  typename JoinSessionCallback,+  typename IoContext,+  typename Clock> Sessions<Peers, MeasurePeer, JoinSessionCallback, IoContext, Clock> makeSessions(   Session init,   util::Injected<Peers> peers,@@ -294,12 +293,8 @@   Clock clock) {   using namespace std;-  return {std::move(init),-          std::move(peers),-          std::move(measure),-          std::move(join),-          std::move(io),-          std::move(clock)};+  return {std::move(init), std::move(peers), std::move(measure), std::move(join),+    std::move(io), std::move(clock)}; }  } // namespace link
link/include/ableton/link/StartStopState.hpp view
@@ -42,9 +42,8 @@    StartStopState() = default; -  StartStopState(const bool aIsPlaying,-                 const Beats aBeats,-                 const std::chrono::microseconds aTimestamp)+  StartStopState(+    const bool aIsPlaying, const Beats aBeats, const std::chrono::microseconds aTimestamp)     : isPlaying(aIsPlaying)     , beats(aBeats)     , timestamp(aTimestamp)@@ -102,8 +101,8 @@   ClientStartStopState() = default;    ClientStartStopState(const bool aIsPlaying,-                       const std::chrono::microseconds aTime,-                       const std::chrono::microseconds aTimestamp)+    const std::chrono::microseconds aTime,+    const std::chrono::microseconds aTimestamp)     : isPlaying(aIsPlaying)     , time(aTime)     , timestamp(aTimestamp)
link/include/ableton/link/Tempo.hpp view
@@ -42,7 +42,10 @@   {   } -  double bpm() const { return mValue; }+  double bpm() const+  {+    return mValue;+  }    std::chrono::microseconds microsPerBeat() const   {@@ -52,8 +55,8 @@   // Given the tempo, convert a time to a beat value   Beats microsToBeats(const std::chrono::microseconds micros) const   {-    return Beats{static_cast<double>(micros.count())-                 / static_cast<double>(microsPerBeat().count())};+    return Beats{+      static_cast<double>(micros.count()) / static_cast<double>(microsPerBeat().count())};   }    // Given the tempo, convert a beat to a time value
+ link/include/ableton/link/TripleBuffer.hpp view
@@ -0,0 +1,121 @@+/* Copyright 2022, Ableton AG, Berlin. All rights reserved.+ *+ *  This program is free software: you can redistribute it and/or modify+ *  it under the terms of the GNU General Public License as published by+ *  the Free Software Foundation, either version 2 of the License, or+ *  (at your option) any later version.+ *+ *  This program is distributed in the hope that it will be useful,+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ *  GNU General Public License for more details.+ *+ *  You should have received a copy of the GNU General Public License+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.+ *+ *  If you would like to incorporate Link into a proprietary software application,+ *  please contact <link-devs@ableton.com>.+ */+++#pragma once++#include <ableton/link/Optional.hpp>++#include <array>+#include <atomic>+#include <cassert>+#include <cstdint>++namespace ableton+{+namespace link+{++template <typename T>+struct TripleBuffer+{+public:+  TripleBuffer()+    : mBuffers{{{}, {}, {}}}+  {+    assert(mState.is_lock_free());+  }++  explicit TripleBuffer(const T& initial)+    : mBuffers{{initial, initial, initial}}+  {+    assert(mState.is_lock_free());+  }++  TripleBuffer(const TripleBuffer&) = delete;+  TripleBuffer& operator=(const TripleBuffer&) = delete;++  T read() noexcept+  {+    loadReadBuffer();+    return mBuffers[mReadIndex];+  }++  Optional<T> readNew()+  {+    if (loadReadBuffer())+    {+      return Optional<T>(mBuffers[mReadIndex]);+    }+    return {};+  }++  template <typename U>+  void write(U&& value)+  {+    mBuffers[mWriteIndex] = std::forward<U>(value);++    const auto prevState =+      mState.exchange(makeState(mWriteIndex, true), std::memory_order_acq_rel);++    mWriteIndex = backIndex(prevState);+  }++private:+  bool loadReadBuffer()+  {+    auto state = mState.load(std::memory_order_acquire);+    auto isNew = isNewWrite(state);+    if (isNew)+    {+      const auto prevState =+        mState.exchange(makeState(mReadIndex, false), std::memory_order_acq_rel);++      mReadIndex = backIndex(prevState);+    }+    return isNew;+  }++  using BackingState = uint32_t;++  static constexpr bool isNewWrite(const BackingState state)+  {+    return (state & 0x0000FFFFu) != 0;+  }++  static constexpr uint32_t backIndex(const BackingState state)+  {+    return state >> 16;+  }++  static constexpr BackingState makeState(+    const uint32_t backBufferIndex, const bool isWrite)+  {+    return (backBufferIndex << 16) | uint32_t(isWrite);+  }++  std::atomic<BackingState> mState{makeState(1u, false)}; // Reader and writer+  uint32_t mReadIndex = 0u;                               // Reader only+  uint32_t mWriteIndex = 2u;                              // Writer only++  std::array<T, 3> mBuffers{};+};++} // namespace link+} // namespace ableton
link/include/ableton/link/v1/Messages.hpp view
@@ -87,9 +87,8 @@   if (messageSize < kMaxMessageSize)   {     return toNetworkByteStream(-      payload,-      toNetworkByteStream(-        header, copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out))));+      payload, toNetworkByteStream(header,+                 copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out))));   }   else   {@@ -126,7 +125,7 @@   // proceed to parse the stream.   if (std::distance(bytesBegin, bytesEnd) >= minMessageSize       && std::equal(-        begin(detail::kProtocolHeader), end(detail::kProtocolHeader), bytesBegin))+           begin(detail::kProtocolHeader), end(detail::kProtocolHeader), bytesBegin))   {     std::tie(header, bytesBegin) =       MessageHeader::fromNetworkByteStream(bytesBegin + protocolHeaderSize, bytesEnd);
@@ -1,56 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#ifndef LINK_API_CONTROLLER--#include <ableton/platforms/Config.hpp>--#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/SessionController.hpp>-#include <ableton/link_audio/Sink.hpp>--namespace ableton-{-namespace link-{--template <typename Clock>-using ApiController = ableton::link_audio::SessionController<PeerCountCallback,-                                                             TempoCallback,-                                                             StartStopStateCallback,-                                                             Clock,-                                                             platform::Random,-                                                             platform::IoContext>;--} // namespace link--using ChannelId = link_audio::Id;-using PeerId = link_audio::Id;-using SessionId = link_audio::Id;--} // namespace ableton--#define LINK_API_CONTROLLER YES--#endif--#include <ableton/Link.hpp>
@@ -1,245 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/link/Beats.hpp>-#include <ableton/link/Tempo.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/v1/Messages.hpp>-#include <algorithm>-#include <array>-#include <numeric>-#include <tuple>-#include <vector>--namespace ableton-{-namespace link_audio-{--using Beats = link::Beats;-using Tempo = link::Tempo;--enum Codec : uint8_t-{-  kInvalid = 0,-  kPCM_i16 = 1,-};-struct AudioBuffer-{-  static constexpr std::int32_t key = '_abu';-  static_assert(key == 0x5f616275, "Unexpected byte order");--  static constexpr std::uint32_t kNonAudioBytes = 50;-  static constexpr uint32_t kMaxAudioBytes = v1::kMaxPayloadSize - kNonAudioBytes;--  struct Chunk-  {-    friend std::uint32_t sizeInByteStream(const Chunk& chunk)-    {-      return discovery::sizeInByteStream(chunk.count)-             + discovery::sizeInByteStream(chunk.numFrames)-             + sizeInByteStream(chunk.beginBeats) + sizeInByteStream(chunk.tempo);-    }--    template <typename It>-    friend It toNetworkByteStream(const Chunk& chunk, It out)-    {-      out = toNetworkByteStream(-        chunk.tempo,-        toNetworkByteStream(-          chunk.beginBeats,-          discovery::toNetworkByteStream(-            chunk.numFrames, discovery::toNetworkByteStream(chunk.count, out))));-      return out;-    }--    template <typename It>-    static std::pair<Chunk, It> fromNetworkByteStream(It begin, It end)-    {-      using namespace std;--      auto [count, countEnd] =-        discovery::Deserialize<uint64_t>::fromNetworkByteStream(begin, end);-      auto [numFrames, numFramesEnd] =-        discovery::Deserialize<uint16_t>::fromNetworkByteStream(countEnd, end);-      auto [beginBeats, beginBeatsEnd] =-        discovery::Deserialize<Beats>::fromNetworkByteStream(numFramesEnd, end);-      auto [tempo, tempoEnd] =-        discovery::Deserialize<Tempo>::fromNetworkByteStream(beginBeatsEnd, end);-      return make_pair(Chunk{count, numFrames, beginBeats, tempo}, tempoEnd);-    }--    friend bool operator==(const Chunk& lhs, const Chunk& rhs)-    {-      return std::tie(lhs.count, lhs.numFrames, lhs.beginBeats, lhs.tempo)-             == std::tie(rhs.count, rhs.numFrames, rhs.beginBeats, rhs.tempo);-    }--    uint64_t count;-    uint16_t numFrames;-    Beats beginBeats;-    Tempo tempo;-  };--  using Chunks = std::vector<Chunk>;-  using Bytes = std::array<uint8_t, kMaxAudioBytes>;--  uint32_t numFrames() const-  {-    return std::accumulate(chunks.begin(),-                           chunks.end(),-                           0u,-                           [](uint32_t sum, const Chunk& chunk)-                           { return sum + chunk.numFrames; });-  }--  // Model the NetworkByteStreamSerializable concept-  friend std::uint32_t sizeInByteStream(const AudioBuffer& buffer)-  {-    return discovery::sizeInByteStream(buffer.channelId)-           + discovery::sizeInByteStream(buffer.sessionId)-           + discovery::sizeInByteStream(buffer.chunks)-           + discovery::sizeInByteStream(static_cast<uint8_t>(buffer.codec))-           + discovery::sizeInByteStream(static_cast<uint32_t>(buffer.sampleRate))-           + discovery::sizeInByteStream(static_cast<int8_t>(buffer.numChannels))-           + discovery::sizeInByteStream(static_cast<int16_t>(buffer.numBytes))-           + static_cast<uint32_t>(buffer.numBytes);-  }--  template <typename It>-  friend It toNetworkByteStream(const AudioBuffer& buffer, It out)-  {-    assert(buffer.codec != Codec::kInvalid);--    out = discovery::toNetworkByteStream(-      static_cast<uint16_t>(buffer.numBytes),-      discovery::toNetworkByteStream(-        static_cast<uint8_t>(buffer.numChannels),-        discovery::toNetworkByteStream(-          static_cast<uint32_t>(buffer.sampleRate),-          discovery::toNetworkByteStream(-            static_cast<uint8_t>(buffer.codec),-            discovery::toNetworkByteStream(-              buffer.chunks,-              discovery::toNetworkByteStream(-                buffer.sessionId,-                discovery::toNetworkByteStream(buffer.channelId, out)))))));--    return std::copy_n(buffer.bytes.begin(), buffer.numBytes, out);-  }--  template <typename It>-  static It fromNetworkByteStream(AudioBuffer& audioBuffer, It begin, It end)-  {-    using namespace std;--    auto [channelId, channelIdEnd] =-      discovery::Deserialize<Id>::fromNetworkByteStream(begin, end);-    audioBuffer.channelId = channelId;--    auto [sessionId, sessionIdEnd] =-      discovery::Deserialize<Id>::fromNetworkByteStream(channelIdEnd, end);-    audioBuffer.sessionId = sessionId;--    auto [chunks, chunksEnd] =-      discovery::Deserialize<Chunks>::fromNetworkByteStream(sessionIdEnd, end);-    audioBuffer.chunks = chunks;--    if (chunks.empty())-    {-      throw runtime_error("Invalid audio buffer: no chunks.");-    }--    auto [codec, codecEnd] =-      discovery::Deserialize<uint8_t>::fromNetworkByteStream(chunksEnd, end);-    audioBuffer.codec = static_cast<Codec>(codec);--    if (codec == Codec::kInvalid)-    {-      throw runtime_error("Invalid codec.");-    }--    auto [sampleRate, sampleRateEnd] =-      discovery::Deserialize<uint32_t>::fromNetworkByteStream(codecEnd, end);-    audioBuffer.sampleRate = sampleRate;--    auto [numChannels, numChannelsEnd] =-      discovery::Deserialize<uint8_t>::fromNetworkByteStream(sampleRateEnd, end);-    audioBuffer.numChannels = numChannels;--    auto [numBytes, numBytesEnd] =-      discovery::Deserialize<uint16_t>::fromNetworkByteStream(numChannelsEnd, end);-    audioBuffer.numBytes = numBytes;--    if (codec == Codec::kPCM_i16-        && audioBuffer.numFrames() * numChannels * sizeof(int16_t) != numBytes)-    {-      throw range_error("Byte count / frame count mismatch.");-    }--    if (std::distance(numBytesEnd, end) > numBytes || numBytesEnd + numBytes > end)-    {-      throw range_error("Invalid byte count.");-    }--    std::copy_n(numBytesEnd, numBytes, audioBuffer.bytes.begin());--    return numBytesEnd + numBytes;-  }--  friend bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs)-  {-    return std::tie(lhs.channelId,-                    lhs.sessionId,-                    lhs.sampleRate,-                    lhs.chunks,-                    lhs.numChannels,-                    lhs.numBytes)-             == std::tie(rhs.channelId,-                         rhs.sessionId,-                         rhs.sampleRate,-                         rhs.chunks,-                         rhs.numChannels,-                         rhs.numBytes)-           && std::equal(lhs.bytes.begin(),-                         lhs.bytes.begin() + lhs.numBytes,-                         begin(rhs.bytes),-                         begin(rhs.bytes) + rhs.numBytes);-  }--  friend bool operator!=(const AudioBuffer& lhs, const AudioBuffer& rhs)-  {-    return !(lhs == rhs);-  }--  Id channelId;-  Id sessionId;-  Chunks chunks;-  Codec codec;-  uint32_t sampleRate;-  uint8_t numChannels;-  uint16_t numBytes;-  Bytes bytes;-};--} // namespace link_audio-} // namespace ableton
@@ -1,50 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/Beats.hpp>-#include <ableton/link/Phase.hpp>-#include <ableton/link/Timeline.hpp>--namespace ableton-{-namespace link_audio-{--static inline link::Beats globalBeatAtBeat(const link::Timeline& timeline,-                                           link::Beats targetBeat,-                                           link::Beats quantum)-{-  const auto beatsDiff =-    link::toPhaseEncodedBeats(timeline, timeline.timeOrigin, quantum);-  return targetBeat - beatsDiff;-}--static inline link::Beats beatAtGlobalBeat(const link::Timeline& timeline,-                                           link::Beats globalBeat,-                                           link::Beats quantum)-{-  const auto beatsDiff =-    link::toPhaseEncodedBeats(timeline, timeline.timeOrigin, quantum);-  return globalBeat + beatsDiff;-}--} // namespace link_audio-} // namespace ableton
@@ -1,67 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/Beats.hpp>-#include <ableton/link/Tempo.hpp>-#include <ableton/link_audio/Id.hpp>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename SampleFormat>-struct Buffer-{-  using SampleFormatType = SampleFormat;-  using Samples = std::vector<SampleFormat>;--  Buffer(uint32_t numSamples)-    : mSamples(numSamples)-  {-  }--  uint32_t mSampleRate;-  uint32_t mNumChannels;-  uint32_t mNumFrames;-  Samples mSamples;-  link::Beats mBeginBeats;-  link::Tempo mTempo;-  uint64_t mCount;-  Id mSessionId;-};--template <typename Buffer>-struct BufferCallbackHandle-{-  BufferCallbackHandle(const Buffer& buffer, typename Buffer::SampleFormatType* pSamples)-    : mBuffer(buffer)-    , mpSamples(pSamples)-  {-  }--  const Buffer& mBuffer;-  typename Buffer::SampleFormatType* mpSamples;-};--} // namespace link_audio-} // namespace ableton
@@ -1,180 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/link_audio/Id.hpp>--namespace ableton-{-namespace link_audio-{--struct ChannelAnnouncement-{-  std::string name;-  Id id;--  // Model the NetworkByteStreamSerializable concept-  friend std::uint32_t sizeInByteStream(const ChannelAnnouncement& channel)-  {-    return discovery::sizeInByteStream(channel.name)-           + discovery::sizeInByteStream(channel.id);-  }--  template <typename It>-  friend It toNetworkByteStream(const ChannelAnnouncement& channel, It out)-  {-    return discovery::toNetworkByteStream(-      channel.id, discovery::toNetworkByteStream(channel.name, std::move(out)));-  }--  template <typename It>-  static std::pair<ChannelAnnouncement, It> fromNetworkByteStream(It begin, It end)-  {-    auto [name, nameEnd] =-      discovery::Deserialize<std::string>::fromNetworkByteStream(begin, end);-    auto [id, idEnd] = discovery::Deserialize<Id>::fromNetworkByteStream(nameEnd, end);-    return std::make_pair(ChannelAnnouncement{std::move(name), std::move(id)}, idEnd);-  }--  friend bool operator==(const ChannelAnnouncement& lhs, const ChannelAnnouncement& rhs)-  {-    return std::tie(lhs.name, lhs.id) == std::tie(rhs.name, rhs.id);-  }-};-;---struct ChannelAnnouncements-{-  static constexpr std::int32_t key = 'auca';-  static_assert(key == 0x61756361, "Unexpected byte order");--  std::vector<ChannelAnnouncement> channels;--  // Model the NetworkByteStreamSerializable concept-  friend std::uint32_t sizeInByteStream(const ChannelAnnouncements& announcements)-  {-    return discovery::sizeInByteStream(announcements.channels);-  }--  template <typename It>-  friend It toNetworkByteStream(const ChannelAnnouncements& announcements, It out)-  {-    return discovery::toNetworkByteStream(announcements.channels, std::move(out));-  }--  template <typename It>-  static std::pair<ChannelAnnouncements, It> fromNetworkByteStream(It begin, It end)-  {-    auto [channels, announcementsEnd] =-      discovery::Deserialize<std::vector<ChannelAnnouncement>>::fromNetworkByteStream(-        std::move(begin), end);-    return std::make_pair(ChannelAnnouncements{channels}, announcementsEnd);-  }--  friend bool operator==(const ChannelAnnouncements& lhs, const ChannelAnnouncements& rhs)-  {-    return lhs.channels == rhs.channels;-  }--  friend bool operator!=(const ChannelAnnouncements& lhs, const ChannelAnnouncements& rhs)-  {-    return !(lhs == rhs);-  }-};--struct ChannelBye-{-  Id id;--  // Model the NetworkByteStreamSerializable concept-  friend std::uint32_t sizeInByteStream(const ChannelBye& bye)-  {-    return discovery::sizeInByteStream(bye.id);-  }--  template <typename It>-  friend It toNetworkByteStream(const ChannelBye& bye, It out)-  {-    return discovery::toNetworkByteStream(bye.id, std::move(out));-  }--  template <typename It>-  static std::pair<ChannelBye, It> fromNetworkByteStream(It begin, It end)-  {-    auto [bye, byeEnd] =-      discovery::Deserialize<Id>::fromNetworkByteStream(std::move(begin), end);-    return std::make_pair(ChannelBye{bye}, byeEnd);-  }--  friend bool operator==(const ChannelBye& lhs, const ChannelBye& rhs)-  {-    return lhs.id == rhs.id;-  }--  friend bool operator!=(const ChannelBye& lhs, const ChannelBye& rhs)-  {-    return !(lhs == rhs);-  }-};--struct ChannelByes-{-  static constexpr std::int32_t key = 'aucb';-  static_assert(key == 0x61756362, "Unexpected byte order");--  std::vector<ChannelBye> byes;--  // Model the NetworkByteStreamSerializable concept-  friend std::uint32_t sizeInByteStream(const ChannelByes& channels)-  {-    return discovery::sizeInByteStream(channels.byes);-  }--  template <typename It>-  friend It toNetworkByteStream(const ChannelByes& channels, It out)-  {-    return discovery::toNetworkByteStream(channels.byes, std::move(out));-  }--  template <typename It>-  static std::pair<ChannelByes, It> fromNetworkByteStream(It begin, It end)-  {-    auto [byes, byesEnd] =-      discovery::Deserialize<std::vector<ChannelBye>>::fromNetworkByteStream(-        std::move(begin), end);-    return std::make_pair(ChannelByes{byes}, byesEnd);-  }--  friend bool operator==(const ChannelByes& lhs, const ChannelByes& rhs)-  {-    return lhs.byes == rhs.byes;-  }--  friend bool operator!=(const ChannelByes& lhs, const ChannelByes& rhs)-  {-    return !(lhs == rhs);-  }-};--} // namespace link_audio-} // namespace ableton
@@ -1,63 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/link_audio/Id.hpp>--namespace ableton-{-namespace link_audio-{--struct ChannelId-{-  static const std::int32_t key = 'chid';-  static_assert(key == 0x63686964, "Unexpected byte order");--  friend bool operator==(const ChannelId& lhs, const ChannelId& rhs)-  {-    return lhs.id == rhs.id;-  }--  // Model the NetworkByteStreamSerializable concept-  friend std::uint32_t sizeInByteStream(const ChannelId& cid)-  {-    return discovery::sizeInByteStream(cid.id);-  }--  template <typename It>-  friend It toNetworkByteStream(const ChannelId& cid, It out)-  {-    return discovery::toNetworkByteStream(cid.id, std::move(out));-  }--  template <typename It>-  static std::pair<ChannelId, It> fromNetworkByteStream(It begin, It end)-  {-    auto [result, itEnd] = discovery::Deserialize<Id>::fromNetworkByteStream(begin, end);-    return std::make_pair(ChannelId{std::move(result)}, itEnd);-  }--  Id id;-};--} // namespace link_audio-} // namespace ableton
@@ -1,92 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/discovery/Payload.hpp>-#include <ableton/link_audio/ChannelId.hpp>--namespace ableton-{-namespace link_audio-{--struct ChannelRequest-{-  using Payload = decltype(discovery::makePayload(ChannelId{}));--  friend bool operator==(const ChannelRequest& lhs, const ChannelRequest& rhs)-  {-    return std::tie(lhs.peerId, lhs.channelId) == std::tie(rhs.peerId, rhs.channelId);-  }--  friend Payload toPayload(const ChannelRequest& request)-  {-    return discovery::makePayload(ChannelId{request.channelId});-  }--  template <typename It>-  static ChannelRequest fromPayload(Id peerId, It begin, It end)-  {-    using namespace std;-    auto request = ChannelRequest{std::move(peerId)};-    discovery::parsePayload<ChannelId>(std::move(begin),-                                       std::move(end),-                                       [&request](ChannelId cid)-                                       { request.channelId = std::move(cid.id); });-    return request;-  }--  Id peerId;-  Id channelId;-};--struct ChannelStopRequest-{-  using Payload = decltype(discovery::makePayload(ChannelId{}));--  friend bool operator==(const ChannelStopRequest& lhs, const ChannelStopRequest& rhs)-  {-    return std::tie(lhs.peerId, lhs.channelId) == std::tie(rhs.peerId, rhs.channelId);-  }--  friend Payload toPayload(const ChannelStopRequest& request)-  {-    return discovery::makePayload(ChannelId{request.channelId});-  }--  template <typename It>-  static ChannelStopRequest fromPayload(Id peerId, It begin, It end)-  {-    using namespace std;-    auto request = ChannelStopRequest{std::move(peerId), {}};-    discovery::parsePayload<ChannelId>(std::move(begin),-                                       std::move(end),-                                       [&request](ChannelId cid)-                                       { request.channelId = std::move(cid.id); });-    return request;-  }--  Id peerId;-  Id channelId;-};--} // namespace link_audio-} // namespace ableton
@@ -1,594 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/link_audio/ChannelAnnouncements.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/PeerAnnouncement.hpp>-#include <ableton/util/Injected.hpp>-#include <algorithm>-#include <cassert>-#include <chrono>-#include <map>-#include <memory>-#include <optional>-#include <stdexcept>-#include <string>-#include <tuple>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename IoContext, typename Callback, typename Interface>-class Channels-{-  // non-movable private implementation type-  struct Impl;--public:-  struct SendHandler-  {-    SendHandler(discovery::UdpEndpoint endpoint, std::shared_ptr<Interface> interface)-      : mEndpoint(endpoint)-      , mpInterface(interface)-    {-    }--    std::size_t operator()(const uint8_t* const pData, const size_t numBytes)-    {-      if (auto interface = mpInterface.lock())-      {-        try-        {-          return interface->send(pData, numBytes, mEndpoint);-        }-        catch (const std::runtime_error&)-        {-        }-      }-      return 0;-    }--    discovery::UdpEndpoint endpoint() const { return mEndpoint; }--  private:-    discovery::UdpEndpoint mEndpoint;-    std::weak_ptr<Interface> mpInterface;-  };--  struct Channel-  {-    std::string name;-    Id id;-    std::string peerName;-    Id peerId;-    Id sessionId;--    friend bool operator==(const Channel& lhs, const Channel& rhs)-    {-      return std::tie(lhs.name, lhs.id, lhs.peerName, lhs.peerId, lhs.sessionId)-             == std::tie(rhs.name, rhs.id, rhs.peerName, rhs.peerId, rhs.sessionId);-    }-  };--  struct ChannelInfo-  {-    Channel channel;-    discovery::IpAddress gatewayAddr;-  };--  struct ChannelInfoCompare-  {-    bool operator()(const ChannelInfo& lhs, const ChannelInfo& rhs) const-    {-      if (lhs.channel.sessionId == rhs.channel.sessionId)-      {-        if (lhs.channel.peerId == rhs.channel.peerId)-        {-          if (lhs.channel.id == rhs.channel.id)-          {-            return lhs.gatewayAddr < rhs.gatewayAddr;-          }-          return lhs.channel.channelId < rhs.channel.channelId;-        }-        return lhs.channel.peerId < rhs.channel.peerId;-      }-      return lhs.channel.sessionId < rhs.channel.sessionId;-    }-  };--  Channels(util::Injected<IoContext> io, Callback callback)-    : mpImpl(std::make_shared<Impl>(std::move(io), std::move(callback)))-  {-  }--  std::vector<Channel> sessionChannels(const link::SessionId& sessionId) const-  {-    using namespace std;-    vector<Channel> result;-    auto& channelsVec = mpImpl->mChannels;-    for (const auto& channel : mpImpl->mChannels)-    {-      if (channel.channel.sessionId == sessionId)-      {-        result.push_back(channel.channel);-      }-    }-    return result;-  }--  std::vector<Channel> uniqueSessionChannels(const link::SessionId& sessionId) const-  {-    auto channels = sessionChannels(sessionId);-    auto it = std::unique(begin(channels),-                          end(channels),-                          [](const auto& a, const auto& b) { return a.id == b.id; });-    return {begin(channels), it};-  }--  std::optional<SendHandler> peerSendHandler(const Id peerId) const-  {-    auto it = mpImpl->mPeerSendHandlers.find(peerId);-    return it != mpImpl->mPeerSendHandlers.end() ? std::optional{it->second.handler}-                                                 : std::nullopt;-  }--  std::optional<SendHandler> channelSendHandler(const Id channelId) const-  {-    const auto& channels = mpImpl->mChannels;-    const auto it =-      std::find_if(begin(channels),-                   end(channels),-                   [&](const auto& info) { return info.channel.id == channelId; });-    return it != end(channels) ? peerSendHandler(it->channel.peerId) : std::nullopt;-  }--  template <typename PeerIdIt>-  void prunePeerChannels(PeerIdIt connectedPeersBegin, PeerIdIt connectedPeersEnd)-  {-    mpImpl->prunePeerChannels(connectedPeersBegin, connectedPeersEnd);-  }--  struct GatewayObserver-  {-    using GatewayObserverAnnouncement = PeerAnnouncement;-    using GatewayObserverNodeId = link::NodeId;--    GatewayObserver(std::shared_ptr<Impl> pImpl, discovery::IpAddress addr)-      : mpImpl(std::move(pImpl))-      , mAddr(std::move(addr))-    {-    }--    GatewayObserver(const GatewayObserver&) = delete;--    GatewayObserver(GatewayObserver&& rhs)-      : mpImpl(std::move(rhs.mpImpl))-      , mAddr(std::move(rhs.mAddr))-    {-    }--    ~GatewayObserver()-    {-      // Check to handle the moved from case-      if (mpImpl)-      {-        mpImpl->gatewayClosed(mAddr);-      }-    }--    // model the observer concept from Channels-    template <typename Announcement>-    friend void sawAnnouncement(GatewayObserver& observer, Announcement announcement)-    {-      auto pImpl = observer.mpImpl;-      auto addr = observer.mAddr;-      assert(pImpl);-      pImpl->sawAnnouncementOnGateway(std::move(announcement), std::move(addr));-    }--    template <typename It>-    friend void channelsLeft(GatewayObserver& observer, It channelsBegin, It channelsEnd)-    {-      auto pImpl = observer.mpImpl;-      auto addr = observer.mAddr;-      pImpl->channelsLeftGateway(std::move(addr), channelsBegin, channelsEnd);-    }--    std::shared_ptr<Impl> mpImpl;-    discovery::IpAddress mAddr;-  };--  // Factory function for the gateway observer-  friend GatewayObserver makeGatewayObserver(Channels& channels,-                                             discovery::IpAddress addr)-  {-    return GatewayObserver{channels.mpImpl, std::move(addr)};-  }--private:-  using Timer = typename util::Injected<IoContext>::type::Timer;-  using TimerError = typename Timer::ErrorCode;-  using TimePoint = typename Timer::TimePoint;--  struct TimeoutCompare-  {-    bool operator()(const std::tuple<TimePoint, discovery::IpAddress, Id>& lhs,-                    const std::tuple<TimePoint, discovery::IpAddress, Id>& rhs) const-    {-      return std::get<TimePoint>(lhs) < std::get<TimePoint>(rhs);-    }-  };--  struct Impl-  {-    Impl(util::Injected<IoContext> io, Callback callback)-      : mIo(std::move(io))-      , mCallback(std::move(callback))-      , mPruneTimer(mIo->makeTimer())-    {-    }--    template <typename Announcement>-    void sawAnnouncementOnGateway(Announcement incoming, discovery::IpAddress gatewayAddr)-    {-      using namespace std;--      const auto peerSession = incoming.announcement.sessionId;-      const auto nodeId = incoming.announcement.nodeId;-      const auto peerInfo = incoming.announcement.peerInfo;-      const auto peerAudioChannels = incoming.announcement.channels.channels;-      const auto ttl = incoming.ttl;-      auto sendHandler = SendHandler(incoming.from, incoming.pInterface);-      const auto networkQuality = incoming.networkQuality;-      bool didChannelsChange = false;--      for (const auto& peerChannel : peerAudioChannels)-      {-        const auto channelInfo = ChannelInfo{-          {peerChannel.name, peerChannel.id, peerInfo.name, nodeId, peerSession},-          gatewayAddr};--        {-          const auto timeout =-            std::find_if(begin(mChannelTimeouts),-                         end(mChannelTimeouts),-                         [&](const auto& timeout)-                         {-                           return std::get<discovery::IpAddress>(timeout) == gatewayAddr-                                  && std::get<Id>(timeout) == channelInfo.channel.id;-                         });-          if (timeout != end(mChannelTimeouts))-          {-            mChannelTimeouts.erase(timeout);-          }--          auto newTo = std::make_tuple(mPruneTimer.now() + std::chrono::seconds(ttl),-                                       gatewayAddr,-                                       channelInfo.channel.id);-          mChannelTimeouts.insert(-            upper_bound(-              begin(mChannelTimeouts), end(mChannelTimeouts), newTo, TimeoutCompare{}),-            newTo);-        }--        const auto idRange = equal_range(begin(mChannels),-                                         end(mChannels),-                                         channelInfo,-                                         [](const auto& a, const auto& b)-                                         { return a.channel.id < b.channel.id; });--        if (idRange.first == idRange.second)-        {-          // This channel is not currently known on any gateway-          didChannelsChange = true;-          mChannels.insert(idRange.first, std::move(channelInfo));-        }-        else-        {-          // was it on this gateway?-          const auto addrRange = equal_range(idRange.first,-                                             idRange.second,-                                             channelInfo,-                                             [](const auto& a, const auto& b)-                                             { return a.gatewayAddr < b.gatewayAddr; });--          if (addrRange.first == addrRange.second)-          {-            // First time on this gateway, add it-            mChannels.insert(addrRange.first, std::move(channelInfo));-          }-          else-          {-            // We have an entry for this channel on this gateway, update it-            // callback if the name of the first entry changed--            auto cmp = [](const auto& lhs, const auto& rhs)-            {-              return std::tie(lhs.name, lhs.sessionId, lhs.peerName, lhs.peerId)-                     == std::tie(rhs.name, rhs.sessionId, rhs.peerName, rhs.peerId);-            };-            const auto firstChannelChanged =-              addrRange.first == idRange.first-              && !cmp(addrRange.first->channel, channelInfo.channel);-            didChannelsChange = didChannelsChange || firstChannelChanged;-            *addrRange.first = std::move(channelInfo);-          }-        }-      }--      if (mPeerSendHandlers.count(nodeId) == 0)-      {-        mPeerSendHandlers.emplace(nodeId, PeerSendHandler{sendHandler, networkQuality});-      }-      else if (mPeerSendHandlers.at(nodeId).networkQuality < networkQuality)-      {-        mPeerSendHandlers.insert_or_assign(-          nodeId, PeerSendHandler{sendHandler, networkQuality});-      }--      // Invoke callbacks outside the critical section-      if (didChannelsChange)-      {-        mCallback();-      }--      scheduleNextPruning();-    }--    template <typename PeerIdIt>-    void prunePeerSendHandlers(PeerIdIt connectedPeersBegin, PeerIdIt connectedPeersEnd)-    {-      using namespace std;-      for (auto it = begin(mPeerSendHandlers); it != end(mPeerSendHandlers);)-      {-        if (none_of(connectedPeersBegin,-                    connectedPeersEnd,-                    [&](const auto& peerId) { return peerId == it->first; }))-        {-          it = mPeerSendHandlers.erase(it);-        }-        else-        {-          ++it;-        }-      }-    }--    void pruneSendHandlers()-    {-      using namespace std;-      auto peerIds = vector<Id>{};-      peerIds.reserve(mChannels.size());-      transform(begin(mChannels),-                end(mChannels),-                back_inserter(peerIds),-                [](const auto& info) { return info.channel.peerId; });-      prunePeerSendHandlers(begin(peerIds), end(peerIds));-    }--    template <typename PeerIdIt>-    void prunePeerChannels(PeerIdIt connectedPeersBegin, PeerIdIt connectedPeersEnd)-    {-      using namespace std;--      vector<Id> removedChannelIds;-      for (const auto& info : mChannels)-      {-        if (none_of(connectedPeersBegin,-                    connectedPeersEnd,-                    [&](const auto& peerId) { return peerId == info.channel.peerId; }))-        {-          removedChannelIds.push_back(info.channel.id);-        }-      }--      auto it = remove_if(begin(mChannels),-                          end(mChannels),-                          [&](auto& info)-                          {-                            return none_of(connectedPeersBegin,-                                           connectedPeersEnd,-                                           [&](const auto& peerId)-                                           { return peerId == info.channel.peerId; });-                          });--      const auto channelsChanged = it != end(mChannels);-      mChannels.erase(it, end(mChannels));--      mChannelTimeouts.erase(-        remove_if(begin(mChannelTimeouts),-                  end(mChannelTimeouts),-                  [&](const auto& timeout)-                  {-                    const auto& id = std::get<Id>(timeout);-                    return find(begin(removedChannelIds), end(removedChannelIds), id)-                           != end(removedChannelIds);-                  }),-        end(mChannelTimeouts));--      scheduleNextPruning();--      prunePeerSendHandlers(connectedPeersBegin, connectedPeersEnd);--      if (channelsChanged)-      {-        mCallback();-      }-    }--    template <typename It>-    void channelsLeftGateway(const discovery::IpAddress& gatewayAddr,-                             It channelsBegin,-                             It channelsEnd)-    {-      using namespace std;--      auto channelsChanged = false;--      for (auto byeIt = channelsBegin; byeIt != channelsEnd; ++byeIt)-      {-        auto bye = *byeIt;--        auto it = remove_if(-          begin(mChannels),-          end(mChannels),-          [&](const auto& info)-          { return info.gatewayAddr == gatewayAddr && bye == info.channel.id; });-        channelsChanged = it != end(mChannels);-        mChannels.erase(it, end(mChannels));--        mChannelTimeouts.erase(remove_if(begin(mChannelTimeouts),-                                         end(mChannelTimeouts),-                                         [&](const auto& timeout)-                                         {-                                           return std::get<discovery::IpAddress>(timeout)-                                                    == gatewayAddr-                                                  && std::get<Id>(timeout) == bye;-                                         }),-                               end(mChannelTimeouts));-      }--      scheduleNextPruning();--      if (channelsChanged)-      {-        pruneSendHandlers();-        mCallback();-      }-    }--    void gatewayClosed(const discovery::IpAddress& gatewayAddr)-    {-      using namespace std;-      auto it =-        remove_if(begin(mChannels),-                  end(mChannels),-                  [&](const auto& info) { return info.gatewayAddr == gatewayAddr; });--      const auto channelsChanged = it != end(mChannels);--      mChannels.erase(it, end(mChannels));--      mChannelTimeouts.erase(-        std::remove_if(-          begin(mChannelTimeouts),-          end(mChannelTimeouts),-          [&](const auto& timeout)-          { return std::get<discovery::IpAddress>(timeout) == gatewayAddr; }),-        end(mChannelTimeouts));--      scheduleNextPruning();--      if (channelsChanged)-      {-        pruneSendHandlers();-        mCallback();-      }-    }--    void pruneExpiredChannels()-    {-      using namespace std;--      const auto test = make_tuple(mPruneTimer.now(), discovery::IpAddress{}, Id{});--      const auto endExpired = lower_bound(-        begin(mChannelTimeouts), end(mChannelTimeouts), test, TimeoutCompare{});--      auto channelsChanged = false;-      if (endExpired != begin(mChannelTimeouts))-      {-        channelsChanged = true;--        for_each(-          begin(mChannelTimeouts),-          endExpired,-          [&](const auto& timeout)-          {-            const auto& id = std::get<Id>(timeout);-            const auto& gatewayAddr = std::get<discovery::IpAddress>(timeout);--            auto it = remove_if(-              begin(mChannels),-              end(mChannels),-              [&](const auto& info)-              { return info.channel.id == id && info.gatewayAddr == gatewayAddr; });--            mChannels.erase(it, end(mChannels));-          });-      }--      mChannelTimeouts.erase(begin(mChannelTimeouts), endExpired);--      scheduleNextPruning();--      if (channelsChanged)-      {-        pruneSendHandlers();-        mCallback();-      }-    }--    void scheduleNextPruning()-    {-      if (!mChannelTimeouts.empty())-      {-        // Add a second of padding to the timer to avoid over-eager timeouts-        const auto t =-          std::get<TimePoint>(mChannelTimeouts.front()) + std::chrono::seconds(1);-        mPruneTimer.expires_at(t);-        mPruneTimer.async_wait(-          [this](const TimerError e)-          {-            if (!e)-            {-              pruneExpiredChannels();-            }-          });-      }-    }--    util::Injected<IoContext> mIo;-    Callback mCallback;-    std::vector<ChannelInfo> mChannels;--    struct PeerSendHandler-    {-      SendHandler handler;-      double networkQuality;-    };-    std::map<Id, PeerSendHandler> mPeerSendHandlers;--    using ChannelTimeout = std::tuple<TimePoint, discovery::IpAddress, Id>;-    using ChannelTimeouts = std::vector<ChannelTimeout>;-    ChannelTimeouts mChannelTimeouts;-    Timer mPruneTimer;-  };--  std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
@@ -1,388 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/link/Controller.hpp>-#include <ableton/link_audio/Channels.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/MainProcessor.hpp>-#include <ableton/link_audio/PeerGateways.hpp>-#include <ableton/link_audio/PeerInfo.hpp>-#include <ableton/link_audio/UdpMessenger.hpp>-#include <ableton/util/Injected.hpp>-#include <ableton/util/Locked.hpp>-#include <algorithm>-#include <atomic>-#include <functional>-#include <optional>-#include <set>-#include <vector>--namespace ableton-{-namespace link_audio-{--using ChannelsChangedCallback = std::function<void()>;-using CallOnThreadFunction = std::function<void()>;--template <typename PeerCountCallback,-          typename TempoCallback,-          typename StartStopStateCallback,-          typename Clock,-          typename Random,-          typename IoContext,-          typename SessionController>-class Controller : public link::Controller<PeerCountCallback,-                                           TempoCallback,-                                           StartStopStateCallback,-                                           Clock,-                                           Random,-                                           IoContext,-                                           SessionController>-{-public:-  using LinkController = link::Controller<PeerCountCallback,-                                          TempoCallback,-                                          StartStopStateCallback,-                                          Clock,-                                          Random,-                                          IoContext,-                                          SessionController>;--  Controller(link::Tempo tempo,-             link::PeerCountCallback peerCallback,-             link::TempoCallback tempoCallback,-             link::StartStopStateCallback startStopStateCallback,-             Clock clock)-    : LinkController(tempo, peerCallback, tempoCallback, startStopStateCallback, clock)-    , mChannelsChangedCallback{[]() {}}-    , mApiChannels({})-    , mIsLinkAudioEnabledByUser(false)-    , mIsLinkAudioEffectivlyEnabled(false)-    , mPeerInfo({})-    , mChannels(util::injectRef(*(this->mIo)), ChannelsChanged{this})-    , mProcessor{util::injectRef(*(this->mIo)), util::injectVal(ChannelsCallback{this})}-    , mGateways{util::injectVal(GatewayFactory{this}), util::injectRef(*(this->mIo))}-  {-  }--  void enableLinkAudio(bool enabled)-  {-    mIsLinkAudioEnabledByUser = enabled;-    this->mRtClientStateSetter.invoke();-  }--  bool isLinkAudioEnabled() const { return mIsLinkAudioEnabledByUser; }---  std::string name() const { return mPeerInfo.read().name; }--  void setName(std::string name)-  {-    this->mIo->async(-      [this, name = std::move(name)]()-      {-        mPeerInfo.update([&, name = std::move(name)](auto& pi)-                         { pi.name = std::move(name); });-        if (this->mpSessionController)-        {-          this->mpSessionController->updateDiscoveryCallback();-        }-      });-  }--  void callOnLinkThread(CallOnThreadFunction func)-  {-    this->mIo->async([func = std::move(func)]() { func(); });-  }--  SharedSink addSink(std::string name, size_t maxNumSamples)-  {-    auto id = Id::random<Random>();-    auto sink = std::make_shared<Sink>(name, maxNumSamples, id);--    this->mIo->async(-      [this, sink]()-      {-        this->mProcessor.addSink(-          sink, util::injectVal(GetSender{this}), util::injectVal(GetNodeId{this}));-        if (this->mpSessionController)-        {-          this->mpSessionController->updateDiscoveryCallback();-        }-      });--    return sink;-  }--  SharedSource addSource(Id channelId, Source::Callback callback)-  {-    auto source = std::make_shared<Source>(std::move(channelId), std::move(callback));--    this->mIo->async(-      [this, source]()-      {-        mProcessor.addSource(-          source, util::injectVal(GetSender{this}), util::injectVal(GetNodeId{this}));-      });--    return source;-  }--  void setChannelsChangedCallback(ChannelsChangedCallback callback)-  {-    this->mIo->async([&, callback = std::move(callback)]()-                     { mChannelsChangedCallback = callback; });-  }--  auto channels() const { return mApiChannels.read(); }--protected:-  void updateIsLinkAudioEnabled()-  {-    const auto shouldBeEnabled = this->mEnabled && mIsLinkAudioEnabledByUser;-    if (shouldBeEnabled && !mIsLinkAudioEffectivlyEnabled)-    {-      mIsLinkAudioEffectivlyEnabled = true;-      this->mpSessionController->gatewaysChangedCallback();-    }-    else if (!shouldBeEnabled && mIsLinkAudioEffectivlyEnabled)-    {-      mIsLinkAudioEffectivlyEnabled = false;-      mGateways.clear();-    }-  }--  void updateAudioDiscovery()-  {-    mGateways.updateAnnouncement(PeerAnnouncement{this->mNodeId,-                                                  this->mSessionId,-                                                  mPeerInfo.read(),-                                                  mProcessor.channelAnnouncements()});-  }--  void updateLinkAudio()-  {-    auto peers = std::set<link::NodeId>();--    for (const auto& sessionPeer : this->mPeers.sessionPeers(this->mSessionId))-    {-      peers.insert(sessionPeer.first.nodeState.ident());-    }--    mGateways.updateSessionPeers(begin(peers), end(peers));--    // Remove channels for peers that are no longer in the session-    mChannels.prunePeerChannels(peers.begin(), peers.end());--    updateApiChannels();-  }--  void sawLinkAudioEndpoint(link::NodeId peerId,-                            std::optional<discovery::UdpEndpoint> endpoint,-                            discovery::IpAddress gateway)-  {-    mGateways.sawLinkAudioEndpoint(peerId, endpoint, gateway);-  }--  void updateLinkAudioGateways()-  {-    auto gateways = std::vector<discovery::IpAddress>();-    this->mDiscovery.withGateways(-      [&](auto begin, auto end)-      { std::for_each(begin, end, [&](auto& it) { gateways.push_back(it.first); }); });--    if (mIsLinkAudioEffectivlyEnabled)-    {-      mGateways.updateGateways(std::move(gateways));-      updateLinkAudio();-    }-    else-    {-      mGateways.clear();-    }-  }--  void updateAudioEndpoints(std::vector<discovery::UdpEndpoint> endpoints)-  {-    this->mDiscovery.withGateways(-      [&](auto begin, auto end)-      {-        std::for_each(begin,-                      end,-                      [&](auto& gateway)-                      {-                        auto it = std::find_if(endpoints.begin(),-                                               endpoints.end(),-                                               [&](const auto& ep)-                                               { return ep.address() == gateway.first; });-                        if (it != endpoints.end())-                        {-                          gateway.second->updateAudioEndpoint(*it);-                        }-                        else-                        {-                          gateway.second->updateAudioEndpoint(std::nullopt);-                        }-                      });-      });-    this->updateDiscovery();-  }--  void updateApiChannels()-  {-    auto channelsChanged = false;-    auto currentChannels = mChannels.uniqueSessionChannels(this->mSessionId);--    std::sort(currentChannels.begin(),-              currentChannels.end(),-              [](const auto& a, const auto& b)-              {-                if (a.peerName == b.peerName)-                {-                  return a.name < b.name;-                }-                return a.peerName < b.peerName;-              });--    mApiChannels.update(-      [&](auto& apiChannels)-      {-        if (apiChannels != currentChannels)-        {-          apiChannels = currentChannels;-          channelsChanged = true;-        }-      });--    if (channelsChanged)-    {-      mChannelsChangedCallback();-    }-  }--  struct ChannelsChanged-  {-    void operator()() { mpController->updateApiChannels(); }--    Controller* mpController;-  };---  using Interface = MessengerInterface<typename util::Injected<IoContext>::type&>;-  using ControllerChannels = Channels<IoContext&, ChannelsChanged, Interface>;-  using SendHandler = typename ControllerChannels::SendHandler;--  struct GetSender-  {-    std::optional<SendHandler> forChannel(const Id& id)-    {-      return mpController->mChannels.channelSendHandler(id);-    }--    std::optional<SendHandler> forPeer(const Id& id)-    {-      return mpController->mChannels.peerSendHandler(id);-    }--    Controller* mpController;-  };--  struct GetNodeId-  {-    const link::NodeId& operator()() const { return mpController->mNodeId; }--    Controller* mpController;-  };--  struct ChannelsCallback-  {-    void operator()()-    {-      if (mpController && mpController->mpSessionController)-      {-        mpController->mpSessionController->updateDiscoveryCallback();-      }-    }--    Controller* mpController;-  };--  using ControllerMainProcessor =-    MainProcessor<ChannelsCallback, GetSender, GetNodeId, Random, IoContext&>;-  using ControllerMessengerPtr =-    MessengerPtr<ControllerMainProcessor&,-                 typename ControllerChannels::GatewayObserver,-                 typename util::Injected<IoContext>::type&>;--  struct GatewayFactory-  {-    ControllerMessengerPtr operator()(const discovery::IpAddress& addr)-    {-      return makeMessengerPtr(-        util::injectRef(mpController->mProcessor),-        util::injectRef(*(mpController->mIo)),-        addr,-        util::injectVal(makeGatewayObserver(mpController->mChannels, addr)),-        PeerAnnouncement{mpController->mNodeId,-                         mpController->mSessionId,-                         mpController->mPeerInfo.read(),-                         mpController->mProcessor.channelAnnouncements()});-    }--    void gatewaysChanged()-    {-      std::vector<discovery::UdpEndpoint> endpoints;-      mpController->mGateways.withGateways(-        [&](auto begin, auto end)-        {-          endpoints.reserve(std::distance(begin, end));-          std::transform(begin,-                         end,-                         std::back_inserter(endpoints),-                         [](auto gateway) { return gateway.second->endpoint(); });-        });-      mpController->updateAudioEndpoints(std::move(endpoints));-    }--    Controller* mpController;-  };--  void stopAudio()-  {-    mIsLinkAudioEnabledByUser = false;-    updateIsLinkAudioEnabled();-    mProcessor.stop();-  }--  ChannelsChangedCallback mChannelsChangedCallback;-  util::Locked<std::vector<typename ControllerChannels::Channel>> mApiChannels;-  std::atomic_bool mIsLinkAudioEnabledByUser;-  bool mIsLinkAudioEffectivlyEnabled;-  util::Locked<PeerInfo> mPeerInfo;-  ControllerChannels mChannels;-  ControllerMainProcessor mProcessor;-  PeerGateways<GatewayFactory, IoContext&> mGateways;-};--} // namespace link_audio-} // namespace ableton
@@ -1,69 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/AudioBuffer.hpp>-#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/PCMCodec.hpp>-#include <ableton/link_audio/Resizer.hpp>-#include <ableton/util/Injected.hpp>-#include <array>-#include <memory>-#include <stdexcept>--namespace ableton-{-namespace link_audio-{--template <typename Sender, typename SampleFormat>-struct Encoder-{-  // TODO: Find the best size for audio buffer messages-  // For now we take RFC 791 as a reference. Nodes must be able to process IP messages of-  // at least 576 bytes.-  static constexpr uint32_t kMaxAudioBytes =-    576 - v1::kHeaderSize - AudioBuffer::kNonAudioBytes;-  static_assert(kMaxAudioBytes <= v1::kMaxPayloadSize);--  Encoder(util::Injected<Sender> sender, Id channelId)-    : mProcessor(-        util::injectVal(PCMEncoder<SampleFormat, Sender>(std::move(sender), channelId)))-  {-  }--  void operator()(const Buffer<SampleFormat>& input)-  {-    mProcessor(input.mSamples.data(),-               input.mNumFrames,-               input.mNumChannels,-               input.mSampleRate,-               input.mBeginBeats,-               input.mTempo,-               input.mSessionId);-  }--private:-  Resizer<SampleFormat, PCMEncoder<SampleFormat, Sender>, kMaxAudioBytes> mProcessor;-};--} // namespace link_audio-} // namespace ableton
@@ -1,32 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/NodeId.hpp>--namespace ableton-{-namespace link_audio-{--using Id = ableton::link::NodeId;--} // namespace link_audio-} // namespace ableton
@@ -1,242 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/ChannelAnnouncements.hpp>-#include <ableton/link_audio/Sink.hpp>-#include <ableton/link_audio/SinkProcessor.hpp>-#include <ableton/link_audio/Source.hpp>-#include <ableton/link_audio/SourceProcessor.hpp>-#include <ableton/util/Injected.hpp>-#include <ableton/util/SafeAsyncHandler.hpp>--namespace ableton-{-namespace link_audio-{--using SharedSink = std::shared_ptr<Sink>;-using SharedSource = std::shared_ptr<Source>;--template <typename ChannelsChangedCallback,-          typename GetSender,-          typename GetNodeId,-          typename Random,-          typename IoContext>-struct MainProcessor-{-  using IoType = typename util::Injected<IoContext>::type;--  static constexpr auto kProcessTimerPeriod = std::chrono::milliseconds(1);--  MainProcessor(util::Injected<IoContext> io,-                util::Injected<ChannelsChangedCallback> callback)-    : mpImpl(std::make_shared<Impl>(std::move(io), std::move(callback)))-  {-  }--  ~MainProcessor() { stop(); }--  void stop() { mpImpl->stop(); }--  void addSink(SharedSink pSink,-               util::Injected<GetSender> getSender,-               util::Injected<GetNodeId> getNodeId)-  {-    mpImpl->addSink(pSink, std::move(getSender), std::move(getNodeId));-  }--  void addSource(SharedSource pSource,-                 util::Injected<GetSender> getSender,-                 util::Injected<GetNodeId> getNodeId)-  {-    mpImpl->addSource(pSource, std::move(getSender), std::move(getNodeId));-  }--  ChannelAnnouncements channelAnnouncements() const-  {-    return mpImpl->channelAnnouncements();-  }--  template <typename Request>-  void receiveChannelRequest(Request request, uint8_t ttl)-  {-    mpImpl->receiveChannelRequest(std::move(request), ttl);-  }--  template <typename It>-  void receiveAudioBuffer(It begin, It end)-  {-    mpImpl->receiveAudioBuffer(begin, end);-  }--private:-  struct Impl : std::enable_shared_from_this<Impl>-  {-    using Timer = typename util::Injected<IoContext>::type::Timer;-    using MainSinkProcessor = SinkProcessor<GetSender, GetNodeId, IoContext&>;-    using MainSourceProcessor = SourceProcessor<GetSender, GetNodeId, IoContext&>;--    Impl(util::Injected<IoContext> io, util::Injected<ChannelsChangedCallback> callback)-      : mIo{std::move(io)}-      , mChannelsChangedCallback{std::move(callback)}-      , mProcessTimer{mIo->makeTimer()}-    {-    }--    void addSink(SharedSink pSink,-                 util::Injected<GetSender> getSender,-                 util::Injected<GetNodeId> getNodeId)-    {-      auto processor = std::make_unique<MainSinkProcessor>(-        util::injectRef(*mIo), pSink, std::move(getSender), std::move(getNodeId));-      mSinks.push_back(std::move(processor));-      start();-    }--    void addSource(SharedSource pSource,-                   util::Injected<GetSender> getSender,-                   util::Injected<GetNodeId> getNodeId)-    {-      auto pProcessor = std::make_unique<MainSourceProcessor>(-        util::injectRef(*mIo), pSource, std::move(getSender), std::move(getNodeId));-      mSources.push_back(std::move(pProcessor));-      start();-    }--    void start() { (*this)(); }--    void stop() { mProcessTimer.cancel(); }--    void operator()()-    {-      processSinks();-      processSources();-      if (!mSinks.empty() || !mSources.empty())-      {-        mProcessTimer.expires_from_now(kProcessTimerPeriod);-        mProcessTimer.async_wait(-          [this](const auto e)-          {-            if (!e)-            {-              (*this)();-            }-          });-      }-    }--    void processSinks()-    {-      auto channelsChanged = false;--      for (auto it = mSinks.begin(); it != mSinks.end();)-      {-        if ((*it)->nameChanged())-        {-          channelsChanged = true;-        }--        if ((*it)->process())-        {-          ++it;-        }-        else-        {-          it = mSinks.erase(it);-          channelsChanged = true;-        }-      }--      if (channelsChanged)-      {-        (*mChannelsChangedCallback)();-      }-    }--    void processSources()-    {-      auto channelsChanged = false;--      for (auto it = mSources.begin(); it != mSources.end();)-      {-        if ((*it)->process())-        {-          ++it;-        }-        else-        {-          it = mSources.erase(it);-        }-      }-    }--    ChannelAnnouncements channelAnnouncements() const-    {-      auto announcements = ChannelAnnouncements{};-      for (auto& sink : mSinks)-      {-        announcements.channels.emplace_back(-          ChannelAnnouncement{sink->name(), sink->id()});-      }-      return announcements;-    }--    template <typename Request>-    void receiveChannelRequest(Request request, uint8_t ttl)-    {-      auto it =-        std::find_if(mSinks.begin(),-                     mSinks.end(),-                     [&](const auto& pSink) { return request.channelId == pSink->id(); });-      if (it != mSinks.end())-      {-        it->get()->receiveChannelRequest(std::move(request), ttl);-      }-    }--    template <typename It>-    void receiveAudioBuffer(It begin, It end)-    {-      static auto audioBuffer = AudioBuffer{};-      AudioBuffer::fromNetworkByteStream(audioBuffer, begin, end);--      auto it = std::find_if(mSources.begin(),-                             mSources.end(),-                             [&](const auto& pSource)-                             { return audioBuffer.channelId == pSource->id(); });-      if (it != mSources.end())-      {-        it->get()->receiveAudioBuffer(audioBuffer);-      }-    }--    util::Injected<IoContext> mIo;-    util::Injected<ChannelsChangedCallback> mChannelsChangedCallback;-    std::vector<std::unique_ptr<MainSinkProcessor>> mSinks;-    std::vector<std::unique_ptr<MainSourceProcessor>> mSources;-    Timer mProcessTimer;-  };--  std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
@@ -1,82 +0,0 @@-#pragma once--#include <array>-#include <chrono>-#include <cmath>-#include <numeric>--namespace ableton-{-namespace link_audio-{--struct NetworkMetricsFilter-{-  struct NetworkMetrics-  {-    double speed;-    double jitter;--    double quality() const { return speed / (1.0 + jitter); }--    bool operator<(const NetworkMetrics& other) const-    {-      return quality() < other.quality();-    }-  };--  NetworkMetricsFilter()-    : mCurrentIndex(0)-    , mCount(0)-  {-  }--  void operator()(std::chrono::microseconds time)-  {-    mPingPongTimes[mCurrentIndex] = time;-    mCurrentIndex = (mCurrentIndex + 1) % kMaxSize;-    if (mCount < kMaxSize)-    {-      ++mCount;-    }-  }--  NetworkMetrics metrics() const-  {-    if (mCount == 0)-    {-      return {0.0, 0.0};-    }--    double sum =-      std::accumulate(mPingPongTimes.begin(),-                      mPingPongTimes.begin() + mCount,-                      0.0,-                      [](auto acc, const auto& time) { return acc + time.count(); });-    double avgRTT = sum / mCount;--    double speed = avgRTT != 0.0 ? 1e6 / avgRTT : 0.0;--    double variance = 0.0;-    for (size_t i = 0; i < mCount; ++i)-    {-      double diff = mPingPongTimes[i].count() - avgRTT;-      variance += diff * diff;-    }-    variance /= mCount;-    double jitter = std::sqrt(variance);--    return {speed, (1e4 - 1e4 * mCount / kMaxSize) + jitter};-  }--  double quality() const { return metrics().quality(); }--private:-  static constexpr size_t kMaxSize = 10;-  std::array<std::chrono::microseconds, kMaxSize> mPingPongTimes;-  size_t mCurrentIndex;-  size_t mCount;-};--} // namespace link_audio-} // namespace ableton
@@ -1,116 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <ableton/link_audio/AudioBuffer.hpp>-#include <ableton/link_audio/Buffer.hpp>-#include <ableton/util/Injected.hpp>-#include <memory>--namespace ableton-{-namespace link_audio-{--template <typename SampleFormat, typename Sender>-struct PCMEncoder-{-  PCMEncoder(util::Injected<Sender> sender, Id channelId)-    : mSender(std::move(sender))-  {-    mOutputBuffer.channelId = channelId;-  }--  void operator()(const SampleFormat* samples,-                  const AudioBuffer::Chunks& chunks,-                  const uint32_t numChannels,-                  const uint32_t sampleRate,-                  const Id sessionId)-  {-    mOutputBuffer.chunks = chunks;-    mOutputBuffer.codec = Codec::kPCM_i16;-    mOutputBuffer.sampleRate = sampleRate;-    mOutputBuffer.numChannels = numChannels;-    mOutputBuffer.sessionId = sessionId;--    auto it = mOutputBuffer.bytes.begin();-    const auto numSamples = mOutputBuffer.numFrames() * mOutputBuffer.numChannels;-    assert(numSamples * sizeof(int16_t) <= AudioBuffer::kMaxAudioBytes);-    for (auto sample = 0u; sample < numSamples; ++sample)-    {-      it = discovery::toNetworkByteStream(samples[sample], it);-    }-    mOutputBuffer.numBytes =-      static_cast<uint32_t>(std::distance(mOutputBuffer.bytes.begin(), it));--    (*mSender)(mOutputBuffer);-  }--  AudioBuffer mOutputBuffer;-  util::Injected<Sender> mSender;-};--template <typename SampleFormat, typename Successor>-struct PCMDecoder-{-  PCMDecoder(util::Injected<Successor> successor, uint32_t cacheSize)-    : mBuffer(cacheSize)-    , mSuccessor(std::move(successor))-  {-  }--  void operator()(const AudioBuffer& input)-  {-    auto it = input.bytes.begin();-    auto numSamples = 0u;-    auto inputEnd = input.bytes.begin() + input.numBytes;-    while (it != inputEnd)-    {-      auto [sample, next] =-        discovery::Deserialize<SampleFormat>::fromNetworkByteStream(it, inputEnd);-      mBuffer.mSamples[numSamples] = sample;-      ++numSamples;-      it = next;-    }--    auto pSamples = mBuffer.mSamples.data();--    for (const auto& [count, numFrames, beginBeats, tempo] : input.chunks)-    {-      mBuffer.mNumFrames = numFrames;-      mBuffer.mNumChannels = input.numChannels;-      mBuffer.mSampleRate = input.sampleRate;-      mBuffer.mBeginBeats = beginBeats;-      mBuffer.mTempo = tempo;-      mBuffer.mCount = count;-      mBuffer.mSessionId = input.sessionId;--      (*mSuccessor)(BufferCallbackHandle<Buffer<SampleFormat>>{mBuffer, pSamples});-      pSamples += numFrames * input.numChannels;-    }-  }--  Buffer<SampleFormat> mBuffer;-  util::Injected<Successor> mSuccessor;-};--} // namespace link_audio-} // namespace ableton
@@ -1,78 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/Payload.hpp>-#include <ableton/link/NodeId.hpp>-#include <ableton/link/SessionId.hpp>-#include <ableton/link_audio/ChannelAnnouncements.hpp>-#include <ableton/link_audio/PeerInfo.hpp>--namespace ableton-{-namespace link_audio-{--struct PeerAnnouncement-{-  using IdType = link::NodeId;--  using Payload = decltype(discovery::makePayload(-    link::SessionMembership{}, PeerInfo{}, ChannelAnnouncements{}));--  link::NodeId ident() const { return nodeId; }--  friend bool operator==(const PeerAnnouncement& lhs, const PeerAnnouncement& rhs)-  {-    return std::tie(lhs.nodeId, lhs.sessionId, lhs.peerInfo, lhs.channels)-           == std::tie(rhs.nodeId, rhs.sessionId, rhs.peerInfo, rhs.channels);-  }--  friend Payload toPayload(const PeerAnnouncement& announcement)-  {-    return discovery::makePayload(link::SessionMembership{announcement.sessionId},-                                  announcement.peerInfo,-                                  announcement.channels);-  }--  template <typename It>-  static PeerAnnouncement fromPayload(link::NodeId nodeId, It begin, It end)-  {-    using namespace std;-    auto announcement = PeerAnnouncement{std::move(nodeId), {}, {}};-    discovery::parsePayload<link::SessionMembership, PeerInfo, ChannelAnnouncements>(-      std::move(begin),-      std::move(end),-      [&announcement](link::SessionMembership membership)-      { announcement.sessionId = std::move(membership.sessionId); },-      [&announcement](PeerInfo pi) { announcement.peerInfo = std::move(pi); },-      [&announcement](ChannelAnnouncements chs)-      { announcement.channels = std::move(chs); });-    return announcement;-  }--  link::NodeId nodeId;-  link::SessionId sessionId;-  PeerInfo peerInfo;-  ChannelAnnouncements channels;-};--} // namespace link_audio-} // namespace ableton
@@ -1,154 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/link/NodeId.hpp>-#include <ableton/util/Injected.hpp>-#include <algorithm>-#include <map>-#include <memory>-#include <optional>-#include <type_traits>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename GatewayFactory, typename IoContext>-struct PeerGateways-{-  using FactoryType = typename util::Injected<GatewayFactory>::type;-  using GatewayPtr = std::invoke_result_t<FactoryType, const discovery::IpAddress&>;-  using GatewayMap = std::map<discovery::IpAddress, GatewayPtr>;--  PeerGateways(util::Injected<GatewayFactory> factory, util::Injected<IoContext> io)-    : mIo(std::move(io))-    , mFactory(std::move(factory))-  {-  }--  template <typename Handler>-  void forEachGateway(Handler handler)-  {-    for (auto it = mGateways.begin(); it != mGateways.end(); ++it)-    {-      handler(it->second);-    }-  }--  template <typename Handler>-  void withGateways(Handler handler)-  {-    handler(mGateways.begin(), mGateways.end());-  }--  void clear()-  {-    mGateways.clear();-    mFactory->gatewaysChanged();-  }--  template <typename Announcement>-  void updateAnnouncement(const Announcement& announcement)-  {-    for (const auto& gateway : mGateways)-    {-      gateway.second->updateAnnouncement(announcement);-    }-  }--  void updateGateways(std::vector<discovery::IpAddress> linkGateways)-  {-    using namespace std;--    vector<discovery::IpAddress> curAddrs;-    curAddrs.reserve(mGateways.size());-    transform(mGateways.begin(),-              mGateways.end(),-              back_inserter(curAddrs),-              [](const auto& gateway) { return gateway.first; });--    vector<discovery::IpAddress> staleAddrs;-    set_difference(curAddrs.begin(),-                   curAddrs.end(),-                   linkGateways.begin(),-                   linkGateways.end(),-                   back_inserter(staleAddrs));--    for (const auto& addr : staleAddrs)-    {-      mGateways.erase(addr);-    }--    vector<discovery::IpAddress> newAddrs;-    set_difference(linkGateways.begin(),-                   linkGateways.end(),-                   curAddrs.begin(),-                   curAddrs.end(),-                   back_inserter(newAddrs));--    for (const auto& addr : newAddrs)-    {-      try-      {-        info(mIo->log()) << "initializing audio gateway on interface " << addr;-        mGateways.emplace(addr, (*mFactory)(addr));-      }-      catch (const std::runtime_error& e)-      {-        warning(mIo->log()) << "failed to init audio gateway on interface " << addr-                            << " reason: " << e.what();-      }-    }--    if (!staleAddrs.empty() || !newAddrs.empty())-    {-      mFactory->gatewaysChanged();-    }-  }--  template <typename It>-  void updateSessionPeers(It peersBegin, It peersEnd)-  {-    forEachGateway([&](auto& gateway)-                   { gateway->pruneChannelsEndpoints(peersBegin, peersEnd); });-  }--  void sawLinkAudioEndpoint(link::NodeId peerId,-                            std::optional<discovery::UdpEndpoint> endpoint,-                            discovery::IpAddress gateway)-  {-    if (auto it = mGateways.find(gateway); it != mGateways.end())-    {-      it->second->sawLinkAudioEndpoint(peerId, endpoint);-    }-  }--private:-  util::Injected<IoContext> mIo;-  GatewayMap mGateways;-  util::Injected<GatewayFactory> mFactory;-};--} // namespace link_audio-} // namespace ableton
@@ -1,75 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/NetworkByteStreamSerializable.hpp>-#include <cstdint>-#include <string>-#include <tuple>--namespace ableton-{-namespace link_audio-{--struct PeerInfo-{-  static const std::int32_t key = '__pi';-  static_assert(key == 0x5f5f7069, "Unexpected byte order");--  friend bool operator==(const PeerInfo& lhs, const PeerInfo& rhs)-  {-    return std::tie(lhs.name) == std::tie(rhs.name);-  }--  friend bool operator!=(const PeerInfo& lhs, const PeerInfo& rhs)-  {-    return !(lhs == rhs);-  }--  // Model the NetworkByteStreamSerializable concept-  friend std::uint32_t sizeInByteStream(const PeerInfo& tl)-  {-    return discovery::sizeInByteStream(tl.name);-  }--  template <typename It>-  friend It toNetworkByteStream(const PeerInfo& tl, It out)-  {-    return discovery::toNetworkByteStream(tl.name, std::move(out));-  }--  template <typename It>-  static std::pair<PeerInfo, It> fromNetworkByteStream(It begin, It end)-  {-    using namespace std;-    using namespace discovery;-    PeerInfo peerInfo;-    auto result =-      Deserialize<std::string>::fromNetworkByteStream(std::move(begin), std::move(end));-    peerInfo.name = std::move(result.first);-    return make_pair(std::move(peerInfo), std::move(result.second));-  }--  std::string name;-};--} // namespace link_audio-} // namespace ableton
@@ -1,217 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <atomic>-#include <memory>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename T>-struct Queue-{-private:-  struct Impl;--public:-  struct Writer-  {-    using SlotType = T;--    Writer(const Writer&) = delete;-    Writer& operator=(const Writer&) = delete;--    Writer(Writer&&) = default;-    Writer& operator=(Writer&&) = default;--    bool retainSlot()-    {-      return mpQueue->retainSlot(mpQueue->mWriterEnd, mpQueue->mReaderBegin);-    }--    void releaseSlot()-    {-      mpQueue->releaseSlot(mpQueue->mWriterBegin, mpQueue->mWriterEnd);-    }--    size_t numRetainedSlots() const-    {-      return mpQueue->numRetainedSlots(mpQueue->mWriterBegin, mpQueue->mWriterEnd);-    }--    size_t numQueuedSlots() const { return mpQueue->numQueuedSlots(); }--    T* operator[](size_t i) const-    {-      if (i < numRetainedSlots())-      {-        i += mpQueue->mWriterBegin.load();-        return mpQueue->mData[i % mpQueue->mData.size()].get();-      }-      return nullptr;-    }--    size_t numSlots() const { return mpQueue->numSlots(); }--  private:-    friend Queue;--    Writer(std::shared_ptr<Impl> pQueue)-      : mpQueue(pQueue)-    {-    }--    std::shared_ptr<Impl> mpQueue;-  };--  struct Reader-  {-    Reader(const Reader&) = delete;-    Reader& operator=(const Reader&) = delete;--    Reader(Reader&&) = default;-    Reader& operator=(Reader&&) = default;--    bool retainSlot()-    {-      return mpQueue->retainSlot(mpQueue->mReaderEnd, mpQueue->mWriterBegin);-    }--    void releaseSlot()-    {-      mpQueue->releaseSlot(mpQueue->mReaderBegin, mpQueue->mReaderEnd);-    }--    size_t numRetainedSlots() const-    {-      return mpQueue->numRetainedSlots(mpQueue->mReaderBegin, mpQueue->mReaderEnd);-    }--    size_t numQueuedSlots() const { return mpQueue->numQueuedSlots(); }--    T* operator[](size_t i) const-    {-      if (i < numRetainedSlots())-      {-        i += mpQueue->mReaderBegin.load() + 1;-        return mpQueue->mData[i % mpQueue->mData.size()].get();-      }-      return nullptr;-    }--    size_t numSlots() const { return mpQueue->numSlots(); }--  private:-    friend Queue;--    Reader(std::shared_ptr<Impl> pQueue)-      : mpQueue(pQueue)-    {-    }--    std::shared_ptr<Impl> mpQueue;-  };--  Queue(size_t numRetainedSlots, const T& t)-    : mpImpl{std::make_shared<Impl>(numRetainedSlots, t)}-  {-  }--  Writer writer() const { return {mpImpl}; }--  Reader reader() const { return {mpImpl}; }--private:-  struct Impl-  {-    Impl(size_t numRetainedSlots, const T& t)-      : mData(numRetainedSlots + 2)-      , mWriterBegin(1)-      , mWriterEnd(1)-      , mReaderBegin(0)-      , mReaderEnd(0)-    {-      for (auto& slot : mData)-      {-        slot = std::make_unique<T>(t);-      }-    }--    inline size_t nextIndex(const size_t index) const-    {-      return (index + 1) % mData.size();-    }--    inline bool retainSlot(std::atomic_size_t& aEnd, std::atomic_size_t& aOtherBegin)-    {-      const auto nextEnd = nextIndex(aEnd.load());-      const auto otherBegin = aOtherBegin.load();-      if (nextEnd != otherBegin)-      {-        aEnd.store(nextEnd);-        return true;-      }-      return false;-    }--    inline void releaseSlot(std::atomic_size_t& aBegin, std::atomic_size_t& aEnd)-    {-      const auto begin = aBegin.load();-      const auto end = aEnd.load();-      if (begin != end)-      {-        aBegin.store(nextIndex(begin));-      }-    }--    inline size_t numRetainedSlots(const std::atomic_size_t& aBegin,-                                   const std::atomic_size_t& aEnd) const-    {-      const auto begin = aBegin.load();-      const auto end = aEnd.load();-      return begin > end ? end + mData.size() - begin : end - begin;-    }--    inline size_t numQueuedSlots() const-    {-      const auto writerBegin = mWriterBegin.load();-      const auto readerEnd = mReaderEnd.load();-      return writerBegin > readerEnd ? writerBegin - readerEnd - 1-                                     : writerBegin + mData.size() - readerEnd - 1;-    }--    size_t numSlots() const { return mData.size() - 2; }--    std::vector<std::unique_ptr<T>> mData;-    std::atomic_size_t mWriterBegin;-    std::atomic_size_t mWriterEnd;-    std::atomic_size_t mReaderBegin;-    std::atomic_size_t mReaderEnd;-  };--  std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
@@ -1,172 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/ChannelRequests.hpp>-#include <ableton/util/Injected.hpp>-#include <chrono>-#include <memory>-#include <utility>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename GetSender, typename IoContext>-class Receivers-{-  using Timer = typename util::Injected<IoContext>::type::Timer;-  using TimePoint = typename Timer::TimePoint;-  using OptionalSendHandler =-    decltype(std::declval<GetSender>().forChannel(std::declval<Id>()));--  struct Receiver-  {-    OptionalSendHandler sendHandler;-    ChannelRequest request;-    TimePoint lastRequest;-  };--public:-  Receivers(util::Injected<IoContext> io, util::Injected<GetSender> getSender)-    : mpImpl(std::make_shared<Impl>(std::move(io), std::move(getSender)))-  {-  }--  void receiveChannelRequest(ChannelRequest request, uint8_t ttl)-  {-    mpImpl->receive(std::move(request), ttl);-  }--  void receiveChannelRequest(ChannelStopRequest stopRequest, uint8_t ttl)-  {-    mpImpl->receive(std::move(stopRequest), ttl);-  }--  void operator()(const uint8_t* const pData, const size_t numBytes)-  {-    (*mpImpl)(pData, numBytes);-  }--  bool empty() const { return mpImpl->empty(); }--private:-  struct Impl-  {-    Impl(util::Injected<IoContext> io, util::Injected<GetSender> getSender)-      : mPruneTimer(io->makeTimer())-      , mGetSender(std::move(getSender))-    {-    }--    void receive(ChannelRequest request, uint8_t ttl)-    {-      const auto it =-        std::find_if(mReceivers.begin(),-                     mReceivers.end(),-                     [&](auto& r) { return r.request.peerId == request.peerId; });-      if (it != mReceivers.end())-      {-        mReceivers.erase(it);-      }--      const auto now = mPruneTimer.now();-      auto receiver = Receiver{-        mGetSender->forPeer(request.peerId), request, now + std::chrono::seconds(ttl)};--      mReceivers.insert(upper_bound(mReceivers.begin(),-                                    mReceivers.end(),-                                    receiver,-                                    [](const auto& r1, const auto& r2)-                                    { return r1.lastRequest < r2.lastRequest; }),-                        std::move(receiver));--      scheduleNextPruning();-    }--    void receive(ChannelStopRequest stopRequest, uint8_t)-    {-      const auto it = std::find_if(mReceivers.begin(),-                                   mReceivers.end(),-                                   [&](const auto& r)-                                   { return r.request.peerId == stopRequest.peerId; });-      if (it != mReceivers.end())-      {-        mReceivers.erase(it);-      };-    }--    void pruneExpiredReceivers()-    {-      const auto test = Receiver{{}, {}, mPruneTimer.now()};--      const auto endExpired = std::lower_bound(-        mReceivers.begin(),-        mReceivers.end(),-        test,-        [](const auto& r1, const auto& r2) { return r1.lastRequest < r2.lastRequest; });--      mReceivers.erase(mReceivers.begin(), endExpired);-      scheduleNextPruning();-    }--    void scheduleNextPruning()-    {-      if (!mReceivers.empty())-      {-        const auto t = mReceivers.front().lastRequest + std::chrono::seconds(1);--        mPruneTimer.expires_at(t);-        mPruneTimer.async_wait(-          [this](const auto e)-          {-            if (!e)-            {-              pruneExpiredReceivers();-            }-          });-      }-    }--    void operator()(const uint8_t* const pData, const size_t numBytes)-    {-      for (auto& receiver : mReceivers)-      {-        if (auto& sendHandler = receiver.sendHandler)-        {-          (*sendHandler)(pData, numBytes);-        }-      }-    }--    bool empty() const { return mReceivers.empty(); }--    Timer mPruneTimer;-    util::Injected<GetSender> mGetSender;-    std::vector<Receiver> mReceivers; // Invariant: sorted by time_point-  };--  std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
@@ -1,147 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software- * application, please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link/Beats.hpp>-#include <ableton/link/Tempo.hpp>-#include <ableton/link_audio/AudioBuffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/util/Injected.hpp>-#include <algorithm>-#include <array>-#include <cmath>-#include <memory>-#include <tuple>-#include <vector>--namespace ableton-{-namespace link_audio-{--template <typename SampleFormat, typename Successor, size_t KMaxNumBytes>-struct Resizer-{-  static constexpr uint32_t kSampleFormatSize =-    static_cast<uint32_t>(sizeof(SampleFormat));-  static constexpr uint32_t kMaxNumSamples = KMaxNumBytes / kSampleFormatSize;--  Resizer(util::Injected<Successor> successor)-    : mSuccessor(std::move(successor))-  {-  }--  void operator()(const SampleFormat* samples,-                  uint32_t numFrames,-                  uint32_t numChannels,-                  uint32_t sampleRate,-                  link::Beats beginBeats,-                  link::Tempo tempo,-                  Id sessionId)-  {-    if (mCachedFrames != 0-        && (numChannels != mNumChannels || sampleRate != mSampleRate-            || sessionId != mSessionId))-    {-      (*mSuccessor)(mCache.data(), mChunks, mNumChannels, mSampleRate, mSessionId);-      mCachedFrames = 0;-      mChunks.clear();-    }--    if (mCachedFrames == 0)-    {-      mSampleRate = sampleRate;-      mNumChannels = numChannels;-      mSessionId = sessionId;-      assert(mChunks.empty());-      newChunk(beginBeats, tempo);-    }-    else if (tempo != mChunks.back().tempo && beginBeats != chunkEndBeats(mChunks.back()))-    {-      newChunk(beginBeats, tempo);-    }--    for (auto frame = 0u; frame < numFrames; ++frame)-    {-      for (auto channel = 0u; channel < mNumChannels; ++channel)-      {-        mCache[mNumChannels * mCachedFrames + channel] =-          samples[mNumChannels * frame + channel];-      }-      ++mCachedFrames;-      ++mChunks.back().numFrames;---      if (mCachedFrames >= ((kMaxNumSamples / mNumChannels)))-      {-        (*mSuccessor)(mCache.data(), mChunks, mNumChannels, mSampleRate, mSessionId);-        mCachedFrames = 0;-        const auto nextChunkBeginBeats = chunkEndBeats(mChunks.back());-        mChunks.clear();--        // Always create a new chunk when needed - don't lose data-        if (frame + 1 < numFrames) // Only if there are more frames to process-        {-          newChunk(nextChunkBeginBeats, tempo);-        }-      }-    }-  }--private:-  link::Beats chunkEndBeats(const AudioBuffer::Chunk& chunk)-  {-    const auto& [count, numFrames, beginBeats, tempo] = chunk;-    const auto secondsPerBeat = 60.0 / tempo.bpm();-    const auto rangeDuration =-      static_cast<double>(numFrames) / static_cast<double>(mSampleRate);-    return beginBeats + link::Beats{rangeDuration / secondsPerBeat};-  }--  uint32_t mCachedFrames = 0;-  uint32_t mAvailableFrames = 0;--  void updateAvailableFrames()-  {-    const auto availableBytes =-      kMaxNumSamples * kSampleFormatSize - discovery::sizeInByteStream(mChunks);-    const auto bytesPerFrame = mNumChannels * kSampleFormatSize;-    const auto offsetBytes = availableBytes % bytesPerFrame;-    mAvailableFrames = (availableBytes - offsetBytes) / bytesPerFrame;-  }--  void newChunk(Beats beats, Tempo tempo)-  {-    mChunks.emplace_back(AudioBuffer::Chunk{++mCount, 0, beats, tempo});-    updateAvailableFrames();-  }--  std::array<SampleFormat, kMaxNumSamples> mCache;-  util::Injected<Successor> mSuccessor;-  uint32_t mNumChannels = 0u;-  uint32_t mSampleRate = 0u;-  Id mSessionId;--  AudioBuffer::Chunks mChunks;-  uint64_t mCount = 0;-};--} // namespace link_audio-} // namespace ableton
@@ -1,125 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/Controller.hpp>-#include <ableton/link_audio/Id.hpp>--namespace ableton-{-namespace link_audio-{--template <typename PeerCountCallback,-          typename TempoCallback,-          typename StartStopStateCallback,-          typename Clock,-          typename Random,-          typename IoContext>-class SessionController : public Controller<PeerCountCallback,-                                            TempoCallback,-                                            StartStopStateCallback,-                                            Clock,-                                            Random,-                                            IoContext,-                                            SessionController<PeerCountCallback,-                                                              TempoCallback,-                                                              StartStopStateCallback,-                                                              Clock,-                                                              Random,-                                                              IoContext>>-{-public:-  using LinkAudioController = Controller<PeerCountCallback,-                                         TempoCallback,-                                         StartStopStateCallback,-                                         Clock,-                                         Random,-                                         IoContext,-                                         SessionController<PeerCountCallback,-                                                           TempoCallback,-                                                           StartStopStateCallback,-                                                           Clock,-                                                           Random,-                                                           IoContext>>;--  SessionController(link::Tempo tempo,-                    PeerCountCallback peerCallback,-                    TempoCallback tempoCallback,-                    StartStopStateCallback startStopStateCallback,-                    Clock clock)-    : LinkAudioController(-        tempo, peerCallback, tempoCallback, startStopStateCallback, clock)-  {-    this->mRtClientStateSetter.start();-  }--  ~SessionController()-  {-    this->mIo->async([this]() { this->stopAudio(); });-    this->shutdown();-  }--  void sessionMembershipCallback()-  {-    this->mSessionPeerCounter();-    this->updateLinkAudio();-  }--  void joinSessionCallback(const link::Session& session)-  {-    this->joinSession(session);-    this->updateLinkAudio();-  }--  template <typename Peer, typename Handler>-  void measurePeerCallback(Peer peer, Handler handler)-  {-    this->measurePeer(std::move(peer), std::move(handler));-  }--  void updateDiscoveryCallback()-  {-    this->updateDiscovery();-    this->updateAudioDiscovery();-  }--  void gatewaysChangedCallback() { this->updateLinkAudioGateways(); }--  void updateRtStatesCallback()-  {-    // Process the pending client states first to make sure we don't push one-    // after we have joined a running session when enabling-    this->mRtClientStateSetter.processPendingClientStates();-    this->mRtClientStateSetter.updateEnabled();--    this->updateIsLinkAudioEnabled();-  }--  void sawAudioEndpointCallback(Id peerId,-                                std::optional<discovery::UdpEndpoint> endpoint,-                                discovery::IpAddress gateway)-  {-    this->sawLinkAudioEndpoint(peerId, endpoint, gateway);-  }-};--} // namespace link_audio-} // namespace ableton
@@ -1,144 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#include <ableton/link_audio/BeatTimeMapping.hpp>-#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/Queue.hpp>-#include <ableton/util/Locked.hpp>-#include <atomic>-#include <string>--#pragma once--namespace ableton-{-namespace link_audio-{--struct Sink-{-  Sink(std::string name, size_t maxNumSamples, Id id)-    : mName{std::move(name)}-    , mId{std::move(id)}-    , mMaxNumSamples{maxNumSamples}-    , mQueue(128, {static_cast<uint32_t>(maxNumSamples)})-    , mIsConnected(false)-  {-  }--  void setName(std::string name)-  {-    mName.update([name = std::move(name)](auto& n) { n = std::move(name); });-    mNameIsUpToDate.clear();-  }--  std::string name() const { return mName.read(); }--  bool nameChanged() { return !mNameIsUpToDate.test_and_set(); }--  const Id& id() const { return mId; }--  Buffer<int16_t>* retainBuffer()-  {-    auto queueWriter = mQueue.writer();--    if (!mIsConnected || queueWriter.numRetainedSlots() > 0)-    {-      return nullptr;-    }--    if (!queueWriter.retainSlot())-    {-      return nullptr;-    }--    if (queueWriter[0]->mSamples.size() < mMaxNumSamples)-    {-      queueWriter.releaseSlot();-      return retainBuffer();-    }--    return queueWriter[0];-  }--  void releaseAndCommitBuffer(const link::Timeline& timeline,-                              const Id& sessionId,-                              double beatsAtBufferBegin,-                              double quantum,-                              size_t numFrames,-                              size_t numChannels,-                              uint32_t sampleRate)-  {-    auto queueWriter = mQueue.writer();--    if (queueWriter.numRetainedSlots() > 0)-    {-      auto pBuffer = queueWriter[0];-      const auto beginBeats =-        globalBeatAtBeat(timeline, link::Beats{beatsAtBufferBegin}, link::Beats{quantum});-      pBuffer->mBeginBeats = beginBeats;-      pBuffer->mTempo = timeline.tempo;-      pBuffer->mNumChannels = static_cast<uint32_t>(numChannels);-      pBuffer->mSampleRate = sampleRate;-      pBuffer->mNumFrames = static_cast<uint32_t>(numFrames);-      pBuffer->mSessionId = sessionId;-      queueWriter.releaseSlot();-    }-  }--  void releaseBuffer()-  {-    auto queueWriter = mQueue.writer();--    assert(queueWriter.numRetainedSlots() > 0);--    if (queueWriter.numRetainedSlots() > 0)-    {-      queueWriter[0]->mBeginBeats = link::Beats{0.};-      queueWriter[0]->mTempo = link::Tempo{0};-      queueWriter.releaseSlot();-    }-  }--  void requestMaxNumSamples(size_t numSamples) { mMaxNumSamples = numSamples; }--  size_t maxNumSamples() const { return mMaxNumSamples; }--  Buffer<int16_t>* buffer()-  {-    auto queueWriter = mQueue.writer();-    return queueWriter.numRetainedSlots() > 0 ? queueWriter[0] : nullptr;-  }--  Queue<Buffer<int16_t>>::Reader reader() { return mQueue.reader(); }--  void setIsConnected(bool isConnected) { mIsConnected = isConnected; }--private:-  util::Locked<std::string> mName;-  std::atomic_flag mNameIsUpToDate = ATOMIC_FLAG_INIT;-  Id mId;-  std::atomic<size_t> mMaxNumSamples;-  Queue<Buffer<int16_t>> mQueue;-  std::atomic<bool> mIsConnected;-};--} // namespace link_audio-} // namespace ableton
@@ -1,146 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/Encoder.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/Receivers.hpp>-#include <ableton/link_audio/Sink.hpp>-#include <ableton/util/Injected.hpp>-#include <memory>-#include <string>--namespace ableton-{-namespace link_audio-{--template <typename GetSender, typename GetNodeId, typename IoContext>-struct SinkProcessor-{-  SinkProcessor(util::Injected<IoContext> io,-                std::shared_ptr<Sink> pSink,-                util::Injected<GetSender> getSender,-                util::Injected<GetNodeId> getNodeId)-    : mpImpl(std::make_shared<Impl>(-        std::move(io), pSink, std::move(getSender), std::move(getNodeId)))-  {-  }--  bool process() { return mpImpl->process(); }--  const Id& id() const { return mpImpl->id(); }--  std::string name() const { return mpImpl->name(); }--  bool nameChanged() { return mpImpl->nameChanged(); }--  template <typename Request>-  void receiveChannelRequest(Request request, uint8_t ttl)-  {-    mpImpl->receiveChannelRequest(std::move(request), ttl);-  }--  struct Impl : public std::enable_shared_from_this<Impl>-  {-    struct Sender-    {-      void operator()(const AudioBuffer& buffer)-      {-        auto end =-          v1::audioBufferMessage((*mpImpl->mGetNodeId)(), buffer, mBuffer.begin());-        try-        {-          mpImpl->mReceivers(mBuffer.data(), std::distance(mBuffer.begin(), end));-        }-        catch (const std::runtime_error& err)-        {-          debug(mpImpl->mIo->log()) << "Failed to send message: " << err.what();-        }-      }--      Impl* mpImpl;-      std::array<uint8_t, v1::kMaxMessageSize> mBuffer{};-    };--    Impl(util::Injected<IoContext> io,-         std::shared_ptr<Sink> pSink,-         util::Injected<GetSender> getSender,-         util::Injected<GetNodeId> getNodeId)-      : mIo(std::move(io))-      , mpSink(pSink)-      , mQueueReader(pSink->reader())-      , mEncoder(util::injectVal(Sender{this}), mpSink->id())-      , mReceivers(util::injectRef(*mIo), std::move(getSender))-      , mGetNodeId(std::move(getNodeId))-    {-    }--    bool process()-    {-      if (mpSink.use_count() <= 1)-      {-        return false;-      }--      while (mQueueReader.retainSlot())-      {-        if (!mReceivers.empty() && mQueueReader[0]->mTempo > link::Tempo{0})-        {-          mEncoder(*mQueueReader[0]);-        }-        if (mQueueReader[0]->mSamples.size() < mpSink->maxNumSamples())-        {-          mQueueReader[0]->mSamples.resize(mpSink->maxNumSamples());-        }-        mQueueReader.releaseSlot();-      }--      return true;-    }--    const Id& id() const { return mpSink->id(); }--    std::string name() const { return mpSink->name(); }--    bool nameChanged() { return mpSink->nameChanged(); }--    template <typename Request>-    void receiveChannelRequest(Request request, uint8_t ttl)-    {-      mReceivers.receiveChannelRequest(std::move(request), ttl);--      mpSink->setIsConnected(!mReceivers.empty());-    }--  private:-    util::Injected<IoContext> mIo;-    std::shared_ptr<Sink> mpSink;-    Queue<Buffer<int16_t>>::Reader mQueueReader;-    Encoder<Sender, int16_t> mEncoder;-    Receivers<GetSender, IoContext> mReceivers;-    util::Injected<GetNodeId> mGetNodeId;-  };--  std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
@@ -1,67 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/Buffer.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/Queue.hpp>-#include <ableton/util/Locked.hpp>--#include <atomic>-#include <optional>--namespace ableton-{-namespace link_audio-{--static constexpr auto kSourceQueueSize = std::chrono::milliseconds(10000);--struct Source-{-  using Callback = std::function<void(BufferCallbackHandle<Buffer<int16_t>>)>;--  Source(Id id, Callback callback)-    : mId(std::move(id))-    , mCallback(std::move(callback))-  {-  }--  const Id& id() const { return mId; }---  void setCallback(Callback newCallback)-  {-    mCallback.update([newCallback_ = std::move(newCallback)](auto& callback)-                     { callback = std::move(newCallback_); });-  }--  void callback(BufferCallbackHandle<Buffer<int16_t>> buffer)-  {-    mCallback.update([&](auto& callback) { callback(buffer); });-  }--private:-  Id mId;-  util::Locked<Callback> mCallback;-};--} // namespace link_audio-} // namespace ableton
@@ -1,159 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/link_audio/ChannelAnnouncements.hpp>-#include <ableton/link_audio/ChannelRequests.hpp>-#include <ableton/link_audio/Id.hpp>-#include <ableton/link_audio/PCMCodec.hpp>-#include <ableton/link_audio/Source.hpp>-#include <ableton/link_audio/v1/Messages.hpp>-#include <ableton/util/Injected.hpp>-#include <optional>-#include <string>--namespace ableton-{-namespace link_audio-{--template <typename GetSender, typename GetNodeId, typename IoContext>-struct SourceProcessor-{-  using Timer = typename util::Injected<IoContext>::type::Timer;-  static constexpr uint8_t kTtl = 5;--  SourceProcessor(util::Injected<IoContext> io,-                  std::shared_ptr<Source> pSource,-                  util::Injected<GetSender> getSender,-                  util::Injected<GetNodeId> getNodeId)-    : mpImpl(std::make_shared<Impl>(-        std::move(io), pSource, std::move(getSender), std::move(getNodeId)))-  {-    mpImpl->sendAudioRequest();-  }--  ~SourceProcessor()-  {-    if (mpImpl != nullptr)-    {-      mpImpl->sendChannelStopRequest();-    }-  }--  bool process() { return mpImpl->process(); }--  void receiveAudioBuffer(const AudioBuffer& buffer)-  {-    mpImpl->receiveAudioBuffer(buffer);-  }--  const Id& id() const { return mpImpl->id(); }--  struct Impl : public std::enable_shared_from_this<Impl>-  {-    Impl(util::Injected<IoContext> io,-         std::shared_ptr<Source> pSource,-         util::Injected<GetSender> getSender,-         util::Injected<GetNodeId> getNodeId)-      : mTimer(io->makeTimer())-      , mpSource(pSource)-      , mGetSender(std::move(getSender))-      , mGetNodeId(std::move(getNodeId))-      , mBuffer(4096 * 2)-      , mDecoder(util::injectVal(Callback{this}), 4096)-    {-    }--    template <typename Payload>-    void sendMessage(const Payload& payload,-                     const v1::MessageType messageType,-                     const uint8_t ttl)-    {-      v1::MessageBuffer buffer;-      const auto messageBegin = buffer.begin();-      const auto messageEnd = v1::detail::encodeMessage(-        (*mGetNodeId)(), ttl, messageType, payload, messageBegin);-      const auto numBytes = static_cast<size_t>(std::distance(messageBegin, messageEnd));-      auto oSender = mGetSender->forChannel(mpSource->id());-      if (oSender)-      {-        try-        {-          (*oSender)(buffer.data(), numBytes);-        }-        catch (const std::runtime_error&)-        {-        }-      }-    }--    void sendAudioRequest()-    {-      mTimer.expires_from_now(std::chrono::seconds(kTtl));-      mTimer.async_wait(-        [this](const auto e)-        {-          if (!e)-          {-            sendAudioRequest();-          }-        });--      const auto request = ChannelRequest{(*mGetNodeId)(), mpSource->id()};-      sendMessage(toPayload(request), v1::kChannelRequest, kTtl);-    }--    void sendChannelStopRequest()-    {-      const auto stopRequest = ChannelStopRequest{(*mGetNodeId)(), mpSource->id()};-      sendMessage(toPayload(stopRequest), v1::kStopChannelRequest, 0);-    }--    bool process() { return mpSource.use_count() > 1; }--    void receiveAudioBuffer(const AudioBuffer& buffer) { mDecoder(buffer); }--    const Id& id() const { return mpSource->id(); }--  private:-    struct Callback-    {-      void operator()(BufferCallbackHandle<Buffer<int16_t>> buffer)-      {-        pImpl->mpSource->callback(buffer);-      }--      Impl* pImpl;-    };--    Timer mTimer;-    std::shared_ptr<Source> mpSource;-    util::Injected<GetSender> mGetSender;-    util::Injected<GetNodeId> mGetNodeId;-    Buffer<int16_t> mBuffer;-    PCMDecoder<int16_t, Callback> mDecoder;-  };--  std::shared_ptr<Impl> mpImpl;-};--} // namespace link_audio-} // namespace ableton
@@ -1,617 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/AsioTypes.hpp>-#include <ableton/discovery/UdpMessenger.hpp>-#include <ableton/discovery/UnicastIpInterface.hpp>-#include <ableton/link/PayloadEntries.hpp>-#include <ableton/link_audio/ChannelRequests.hpp>-#include <ableton/link_audio/NetworkMetrics.hpp>-#include <ableton/link_audio/v1/Messages.hpp>-#include <ableton/util/Injected.hpp>-#include <ableton/util/SafeAsyncHandler.hpp>-#include <algorithm>-#include <chrono>-#include <memory>-#include <optional>-#include <stdexcept>-#include <vector>--namespace ableton-{-namespace link_audio-{--// Throws UdpSendException-template <typename Interface, typename NodeId, typename Payload>-void sendLinkAudioUdpMessage(Interface& iface,-                             NodeId from,-                             const uint8_t ttl,-                             const v1::MessageType messageType,-                             const Payload& payload,-                             const discovery::UdpEndpoint& to)-{-  using namespace std;-  v1::MessageBuffer buffer;-  const auto messageBegin = begin(buffer);-  try-  {-    const auto messageEnd =-      v1::detail::encodeMessage(std::move(from), ttl, messageType, payload, messageBegin);-    const auto numBytes = static_cast<size_t>(distance(messageBegin, messageEnd));-    iface.send(buffer.data(), numBytes, to);-  }-  catch (const std::runtime_error& err)-  {-    throw discovery::UdpSendException{err, iface.endpoint().address()};-  }-}--// UdpMessenger uses a "shared_ptr pImpl" pattern to make it movable-// and to support safe async handler callbacks when receiving messages-// on the given interface.-template <typename ChannelsMessageHandler,-          typename Interface,-          typename Observer,-          typename IoContext>-class UdpMessenger-{-public:-  using ObserverType = typename util::Injected<Observer>::type;-  using Announcement = typename ObserverType::GatewayObserverAnnouncement;-  using NodeId = typename ObserverType::GatewayObserverNodeId;-  using Timer = typename util::Injected<IoContext>::type::Timer;-  using TimerError = typename Timer::ErrorCode;-  using TimePoint = typename Timer::TimePoint;-  using SharedInterface = std::shared_ptr<Interface>;--  struct ExtendedAnnouncement-  {-    link::NodeId ident() const { return announcement.ident(); }--    Announcement announcement;-    double networkQuality;-    SharedInterface pInterface;-    discovery::UdpEndpoint from;-    int ttl;-  };--  UdpMessenger(util::Injected<ChannelsMessageHandler> handler,-               SharedInterface pIface,-               Announcement announcement,-               util::Injected<IoContext> io,-               const uint8_t ttl,-               const uint8_t ttlRatio,-               util::Injected<Observer> observer)-    : mpImpl(std::make_shared<Impl>(std::move(handler),-                                    std::move(pIface),-                                    std::move(announcement),-                                    std::move(io),-                                    ttl,-                                    ttlRatio,-                                    std::move(observer)))-  {-    // We need to always listen for incoming traffic in order to-    // respond to announcement broadcasts-    mpImpl->listen();-    mpImpl->broadcastAnnouncement();-  }--  UdpMessenger(const UdpMessenger&) = delete;-  UdpMessenger& operator=(const UdpMessenger&) = delete;--  UdpMessenger(UdpMessenger&& rhs)-    : mpImpl(std::move(rhs.mpImpl))-  {-  }--  ~UdpMessenger()-  {-    if (mpImpl != nullptr)-    {-      mpImpl->mTimer.cancel();-      mpImpl->sendAudioChannelByes({});-    }-  }--  void updateAnnouncement(Announcement announcement)-  {-    mpImpl->updateAnnouncement(std::move(announcement));-  }--  discovery::UdpEndpoint endpoint() const { return mpImpl->mpInterface->endpoint(); }--  template <typename It>-  void pruneChannelsEndpoints(It peersBegin, It peersEnd)-  {-    auto it = std::remove_if(-      mpImpl->mReceivers.begin(),-      mpImpl->mReceivers.end(),-      [&](const auto& r)-      {-        return std::none_of(-          peersBegin, peersEnd, [&](const auto& peerId) { return peerId == r.id; });-      });--    mpImpl->mReceivers.erase(it, mpImpl->mReceivers.end());-  }--  void sawLinkAudioEndpoint(link::NodeId peerId,-                            std::optional<discovery::UdpEndpoint> endpoint)-  {-    if (endpoint)-    {-      if (endpoint->address().is_v6())-      {-        *endpoint = discovery::ipV6Endpoint(*mpImpl->mpInterface, *endpoint);-      }-      auto it =-        std::find_if(mpImpl->mReceivers.begin(),-                     mpImpl->mReceivers.end(),-                     [&](const auto& receiver) { return receiver.endpoint == endpoint; });-      if (it == mpImpl->mReceivers.end())-      {-        mpImpl->mReceivers.push_back({peerId, *endpoint, {}});-      }-    }-    else-    {-      auto it = std::remove_if(mpImpl->mReceivers.begin(),-                               mpImpl->mReceivers.end(),-                               [&](const auto& r) { return r.id == peerId; });--      mpImpl->mReceivers.erase(it, mpImpl->mReceivers.end());-    }-  }--private:-  struct Receiver-  {-    link::NodeId id;-    discovery::UdpEndpoint endpoint;-    NetworkMetricsFilter metricsFilter;-  };--  struct Impl : std::enable_shared_from_this<Impl>-  {-    Impl(util::Injected<ChannelsMessageHandler> handler,-         SharedInterface pIface,-         Announcement announcement,-         util::Injected<IoContext> io,-         const uint8_t ttl,-         const uint8_t ttlRatio,-         util::Injected<Observer> observer)-      : mIo(std::move(io))-      , mChannelsMessageHandler(std::move(handler))-      , mpInterface(std::move(pIface))-      , mTimer(mIo->makeTimer())-      , mLastBroadcastTime{}-      , mTtl(ttl)-      , mTtlRatio(ttlRatio)-      , mObserver(std::move(observer))-    {-      updateAnnouncement(std::move(announcement));-    }--    void sendAudioChannelByes(const ChannelAnnouncements& newAnnouncements)-    {-      auto channelByes = ChannelByes{};-      for (const auto& announcement : mAnnouncements)-      {-        for (const auto& channel : announcement.channels.channels)-        {-          if (std::none_of(newAnnouncements.channels.begin(),-                           newAnnouncements.channels.end(),-                           [&](const auto& c) { return c.id == channel.id; }))-          {-            channelByes.byes.push_back({channel.id});-          }-        }-      }--      if (channelByes.byes.size() > 0)-      {-        auto byesToSend = std::vector<ChannelByes>{{}};--        for (const auto& bye : channelByes.byes)-        {-          auto addedSize = sizeInByteStream(bye);-          if (sizeInByteStream(byesToSend.back()) + addedSize > v1::kMaxPayloadSize)-          {-            byesToSend.emplace_back();-          }-          byesToSend.back().byes.push_back(bye);-        }--        for (const auto& receiver : mReceivers)-        {-          for (const auto& byes : byesToSend)-          {-            try-            {-              sendLinkAudioUdpMessage(*mpInterface,-                                      mAnnouncements.back().ident(),-                                      mTtl,-                                      v1::kChannelByes,-                                      discovery::makePayload(byes),-                                      receiver.endpoint);-            }-            catch (const discovery::UdpSendException&)-            {-            }-          }-        }-      }-    }--    void updateAnnouncement(Announcement announcement)-    {-      sendAudioChannelByes(announcement.channels);-      const auto pingPayload = discovery::makePayload(link::HostTime{});-      const auto pingSize = sizeInByteStream(pingPayload);-      mAnnouncements = {Announcement{-        announcement.nodeId, announcement.sessionId, announcement.peerInfo, {}}};--      for (const auto& channel : announcement.channels.channels)-      {-        const auto channelSize = sizeInByteStream(channel);-        // A ping is sent along with the first announcement-        auto addedSize =-          mAnnouncements.size() == 1 ? channelSize + pingSize : channelSize;-        if (sizeInByteStream(toPayload(mAnnouncements.back())) + addedSize-            > v1::kMaxPayloadSize)-        {-          mAnnouncements.push_back(Announcement{-            announcement.nodeId, announcement.sessionId, announcement.peerInfo, {}});-        }-        mAnnouncements.back().channels.channels.push_back(channel);-      }-    }--    void broadcastAnnouncement()-    {-      using namespace std::chrono;--      const auto minBroadcastPeriod = milliseconds{50};-      const auto nominalBroadcastPeriod = milliseconds(mTtl * 1000 / mTtlRatio);-      const auto timeSinceLastBroadcast =-        duration_cast<milliseconds>(mTimer.now() - mLastBroadcastTime);--      // The rate is limited to maxBroadcastRate to prevent flooding the network.-      const auto delay = minBroadcastPeriod - timeSinceLastBroadcast;--      // Schedule the next broadcast before we actually send the-      // message so that if sending throws an exception we are still-      // scheduled to try again. We want to keep trying at our-      // interval as long as this instance is alive.-      mTimer.expires_from_now(delay > milliseconds{0} ? delay : nominalBroadcastPeriod);-      mTimer.async_wait(-        [this](const TimerError e)-        {-          if (!e)-          {-            broadcastAnnouncement();-          }-        });--      // // If we're not delaying, broadcast now-      if (delay < milliseconds{1})-      {-        debug(mIo->log()) << "Broadcasting Announcement";-        sendAnnouncement();-      }-    }--    void sendAnnouncement()-    {-      const auto pingTime = std::chrono::duration_cast<std::chrono::microseconds>(-        mTimer.now().time_since_epoch());-      for (auto& receiver : mReceivers)-      {-        try-        {-          // Send one ping per receiver-          auto shouldSendPing = true;-          for (const auto& announcement : mAnnouncements)-          {-            if (shouldSendPing)-            {-              const auto hostTime = link::HostTime{pingTime};-              sendLinkAudioUdpMessage(-                *mpInterface,-                announcement.ident(),-                mTtl,-                v1::kPeerAnnouncement,-                toPayload(announcement) + discovery::makePayload(hostTime),-                receiver.endpoint);-              shouldSendPing = false;-            }-            else-            {-              sendLinkAudioUdpMessage(*mpInterface,-                                      announcement.ident(),-                                      mTtl,-                                      v1::kPeerAnnouncement,-                                      toPayload(announcement),-                                      receiver.endpoint);-            }-          }-        }-        catch (const discovery::UdpSendException&)-        {-        }-      }-      mLastBroadcastTime = mTimer.now();-    }--    void listen() { mpInterface->receive(util::makeAsyncSafe(this->shared_from_this())); }--    template <typename It>-    void operator()(const discovery::UdpEndpoint& from,-                    const It messageBegin,-                    const It messageEnd)-    {-      auto result = v1::parseMessageHeader(messageBegin, messageEnd);--      const auto& header = result.first;-      // Ignore messages from self and other groups-      if (header.ident != mAnnouncements.front().ident() && header.groupId == 0)-      {-        debug(mIo->log()) << "Received message type "-                          << static_cast<int>(header.messageType) << " from peer "-                          << header.ident;--        switch (header.messageType)-        {-        case v1::kPeerAnnouncement:-          receiveAnnouncement(std::move(result.first), result.second, messageEnd, from);-          receivePing(result.second, messageEnd, from);-          break;-        case v1::kChannelByes:-          receiveChannelByes(result.second, messageEnd);-          break;-        case v1::kPong:-          receivePong(result.second, messageEnd, from);-          break;-        case v1::kChannelRequest:-          receiveChannelRequest(std::move(result.first), result.second, messageEnd);-          break;-        case v1::kStopChannelRequest:-          receiveChannelStopRequest(std::move(result.first), result.second, messageEnd);-          break;-        case v1::kAudioBuffer:-          receiveAudioBuffer(std::move(result.first), result.second, messageEnd);-          break;-        default:-          info(mIo->log()) << "Unknown message received of type: " << header.messageType;-        }-      }-      listen();-    }--    template <typename It>-    void receivePing(It payloadBegin, It payloadEnd, discovery::UdpEndpoint from)-    {-      std::optional<std::chrono::microseconds> oHostTime;-      discovery::parsePayload<link::HostTime>(payloadBegin,-                                              payloadEnd,-                                              [&oHostTime](link::HostTime ht)-                                              { oHostTime = std::move(ht.time); });--      if (oHostTime)-      {-        try-        {-          sendLinkAudioUdpMessage(*mpInterface,-                                  mAnnouncements.front().ident(),-                                  mTtl,-                                  v1::kPong,-                                  discovery::makePayload(link::HostTime{*oHostTime}),-                                  from);-        }-        catch (const std::runtime_error& err)-        {-          return;-        }-      }-    }--    template <typename It>-    void receivePong(It payloadBegin, It payloadEnd, discovery::UdpEndpoint from)-    {-      const auto receiveTime = std::chrono::duration_cast<std::chrono::microseconds>(-        mTimer.now().time_since_epoch());-      std::chrono::microseconds sendTime{0};--      try-      {-        discovery::parsePayload<link::HostTime>(payloadBegin,-                                                payloadEnd,-                                                [&sendTime](link::HostTime ht)-                                                { sendTime = std::move(ht.time); });--        auto it =-          std::find_if(mReceivers.begin(),-                       mReceivers.end(),-                       [&](const auto& receiver) { return receiver.endpoint == from; });-        if (it != mReceivers.end())-        {-          it->metricsFilter(receiveTime - sendTime);-        }-      }-      catch (const std::runtime_error& err)-      {-        return;-      }-    }--    template <typename It>-    void receiveAnnouncement(v1::MessageHeader header,-                             It payloadBegin,-                             It payloadEnd,-                             discovery::UdpEndpoint from)-    {-      const auto it =-        std::find_if(mReceivers.begin(),-                     mReceivers.end(),-                     [&](const auto& receiver) { return receiver.endpoint == from; });--      if (it != mReceivers.end())-      {-        try-        {-          auto announcement = Announcement::fromPayload(-            std::move(header.ident), std::move(payloadBegin), std::move(payloadEnd));--          sawAnnouncement(*mObserver,-                          ExtendedAnnouncement{std::move(announcement),-                                               it->metricsFilter.metrics().quality(),-                                               mpInterface,-                                               from,-                                               mTtl});-        }-        catch (const std::runtime_error& err)-        {-          info(mIo->log()) << "Ignoring peer announcement message: " << err.what();-        }-      }-    }--    template <typename It>-    void receiveChannelByes(It payloadBegin, It payloadEnd)-    {-      auto byes = ChannelByes{};-      discovery::parsePayload<ChannelByes>(-        payloadBegin, payloadEnd, [&](const auto& b) { byes = std::move(b); });--      std::vector<NodeId> byesVector;-      for (const auto& bye : byes.byes)-      {-        byesVector.push_back(bye.id);-      }--      channelsLeft(*mObserver, begin(byesVector), end(byesVector));-    }--    template <typename It>-    void receiveChannelRequest(v1::MessageHeader header, It payloadBegin, It payloadEnd)-    {-      try-      {-        auto request = ChannelRequest::fromPayload(-          std::move(header.ident), std::move(payloadBegin), std::move(payloadEnd));-        mChannelsMessageHandler->receiveChannelRequest(request, header.ttl);-      }-      catch (const std::runtime_error& err)-      {-        info(mIo->log()) << "Ignoring AudioRequest message: " << err.what();-      }-    }--    template <typename It>-    void receiveChannelStopRequest(v1::MessageHeader header,-                                   It payloadBegin,-                                   It payloadEnd)-    {-      try-      {-        auto stopRequest = ChannelStopRequest::fromPayload(-          std::move(header.ident), std::move(payloadBegin), std::move(payloadEnd));-        mChannelsMessageHandler->receiveChannelRequest(stopRequest, header.ttl);-      }-      catch (const std::runtime_error& err)-      {-        info(mIo->log()) << "Ignoring ChannelStopRequest message: " << err.what();-      }-    }--    template <typename It>-    void receiveAudioBuffer(v1::MessageHeader header, It payloadBegin, It payloadEnd)-    {-      try-      {-        mChannelsMessageHandler->receiveAudioBuffer(payloadBegin, payloadEnd);-      }-      catch (const std::runtime_error& err)-      {-        info(mIo->log()) << "Ignoring AudioBuffer message: " << err.what();-      }-    }--    util::Injected<IoContext> mIo;-    util::Injected<ChannelsMessageHandler> mChannelsMessageHandler;-    SharedInterface mpInterface;-    std::vector<Announcement> mAnnouncements;-    Timer mTimer;-    TimePoint mLastBroadcastTime;-    uint8_t mTtl;-    uint8_t mTtlRatio;-    util::Injected<Observer> mObserver;-    std::vector<Receiver> mReceivers;-  };--  std::shared_ptr<Impl> mpImpl;-};--template <typename IoContext>-using MessengerInterface =-  UnicastIpInterface<typename util::Injected<IoContext>::type&, v1::kMaxMessageSize>;-template <typename IoContext>-using MessengerInterface = MessengerInterface<IoContext>;-template <typename ChannelsMessageHandler, typename Observer, typename IoContext>-using Messenger = UdpMessenger<ChannelsMessageHandler,-                               MessengerInterface<IoContext>,-                               Observer,-                               IoContext>;-template <typename ChannelsMessageHandler, typename Observer, typename IoContext>-using MessengerPtr =-  std::shared_ptr<Messenger<ChannelsMessageHandler, Observer, IoContext>>;--// Factory function-template <typename ChannelsMessageHandler,-          typename Announcement,-          typename IoContext,-          typename Observer>-MessengerPtr<ChannelsMessageHandler, Observer, IoContext> makeMessengerPtr(-  util::Injected<ChannelsMessageHandler> handler,-  util::Injected<IoContext> io,-  const discovery::IpAddress& addr,-  util::Injected<Observer> observer,-  Announcement announcement)-{-  const uint8_t ttl = 5;-  const uint8_t ttlRatio = 20;--  auto pIface =-    makeSharedUnicastIpInterface<v1::kMaxMessageSize>(util::injectRef(*io), addr);--  return std::make_shared<Messenger<ChannelsMessageHandler, Observer, IoContext>>(-    std::move(handler),-    pIface,-    std::move(announcement),-    std::move(io),-    ttl,-    ttlRatio,-    std::move(observer));-}--} // namespace link_audio-} // namespace ableton
@@ -1,170 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */--#pragma once--#include <ableton/discovery/Payload.hpp>-#include <ableton/link/NodeId.hpp>-#include <array>--namespace ableton-{-namespace link_audio-{-namespace v1-{--// To define the maximum message size, we need to consider the maximum transmission unit-// (MTU) of the network and the IP and UDP header sizes. To avoid fragmentation, the-// message size should be smaller than the MTU. For IPv4 ethernet networks the standard is-// 1500 bytes and for IPv6 it's 1280 bytes. The IPv4 header can be extended to 60 bytes-// while the IPv6 header is fixed at 40 bytes. The UPD header's size is 8 bytes.-static constexpr std::size_t kMaxMessageSize = 1200;-static constexpr std::size_t kHeaderSize = 24;-static constexpr std::size_t kMaxPayloadSize = kMaxMessageSize - kHeaderSize;-static constexpr std::size_t kMaxNameSize = 256;-// Utility typedef for an array of bytes of maximum message size-using MessageBuffer = std::array<uint8_t, v1::kMaxMessageSize>;--using MessageType = uint8_t;-using SessionGroupId = uint16_t;--const MessageType kInvalid = 0;-const MessageType kPeerAnnouncement = 1;-const MessageType kChannelByes = 2;-const MessageType kPong = 3;-const MessageType kChannelRequest = 4;-const MessageType kStopChannelRequest = 5;-const MessageType kAudioBuffer = 6;--struct MessageHeader-{-  MessageType messageType;-  uint8_t ttl;-  SessionGroupId groupId;-  link::NodeId ident;--  friend std::uint32_t sizeInByteStream(const MessageHeader& header)-  {-    return discovery::sizeInByteStream(header.messageType)-           + discovery::sizeInByteStream(header.ttl)-           + discovery::sizeInByteStream(header.groupId)-           + discovery::sizeInByteStream(header.ident);-  }--  template <typename It>-  friend It toNetworkByteStream(const MessageHeader& header, It out)-  {-    return discovery::toNetworkByteStream(-      header.ident,-      discovery::toNetworkByteStream(-        header.groupId,-        discovery::toNetworkByteStream(-          header.ttl,-          discovery::toNetworkByteStream(header.messageType, std::move(out)))));-  }--  template <typename It>-  static std::pair<MessageHeader, It> fromNetworkByteStream(It begin, const It end)-  {-    using namespace std;--    MessageHeader header;-    tie(header.messageType, begin) =-      discovery::Deserialize<decltype(header.messageType)>::fromNetworkByteStream(-        begin, end);-    tie(header.ttl, begin) =-      discovery::Deserialize<decltype(header.ttl)>::fromNetworkByteStream(begin, end);-    tie(header.groupId, begin) =-      discovery::Deserialize<decltype(header.groupId)>::fromNetworkByteStream(begin, end);-    tie(header.ident, begin) =-      discovery::Deserialize<decltype(header.ident)>::fromNetworkByteStream(begin, end);--    return make_pair(std::move(header), std::move(begin));-  }-};--namespace detail-{--// Types that are only used in the sending/parsing of messages, not-// publicly exposed.-using ProtocolHeader = std::array<char, 8>;-const ProtocolHeader kProtocolHeader = {{'c', 'h', 'n', 'n', 'l', 's', 'v', 1}};--// Must have at least kMaxMessageSize bytes available in the output stream-template <typename Payload, typename It>-It encodeMessage(link::NodeId from,-                 const uint8_t ttl,-                 const MessageType messageType,-                 const Payload& payload,-                 It out)-{-  using namespace std;-  const MessageHeader header = {messageType, ttl, 0, std::move(from)};-  const auto messageSize =-    kProtocolHeader.size() + sizeInByteStream(header) + sizeInByteStream(payload);--  if (messageSize <= kMaxMessageSize)-  {-    return toNetworkByteStream(-      payload,-      toNetworkByteStream(-        header, copy(begin(kProtocolHeader), end(kProtocolHeader), std::move(out))));-  }-  else-  {-    throw range_error("Exceeded maximum message size");-  }-}--} // namespace detail--template <typename Payload, typename It>-It audioBufferMessage(link::NodeId from, const Payload& payload, It out)-{-  return detail::encodeMessage(std::move(from), 0, kAudioBuffer, payload, std::move(out));-}--template <typename It>-std::pair<MessageHeader, It> parseMessageHeader(It bytesBegin, const It bytesEnd)-{-  using namespace std;-  using ItDiff = typename iterator_traits<It>::difference_type;--  MessageHeader header = {};-  const auto protocolHeaderSize = discovery::sizeInByteStream(detail::kProtocolHeader);-  const auto minMessageSize =-    static_cast<ItDiff>(protocolHeaderSize + sizeInByteStream(header));--  // If there are enough bytes in the stream to make a header and if-  // the first bytes in the stream are the protocol header, then-  // proceed to parse the stream.-  if (distance(bytesBegin, bytesEnd) >= minMessageSize-      && equal(begin(detail::kProtocolHeader), end(detail::kProtocolHeader), bytesBegin))-  {-    tie(header, bytesBegin) =-      MessageHeader::fromNetworkByteStream(bytesBegin + protocolHeaderSize, bytesEnd);-  }-  return make_pair(std::move(header), std::move(bytesBegin));-}--} // namespace v1-} // namespace link_audio-} // namespace ableton
link/include/ableton/platforms/Config.hpp view
@@ -20,7 +20,6 @@ #pragma once  #include <ableton/link/Controller.hpp>-#include <ableton/link/SessionController.hpp> #include <ableton/util/Log.hpp>  #if defined(LINK_PLATFORM_WINDOWS)@@ -28,7 +27,9 @@ #include <ableton/platforms/stl/Random.hpp> #include <ableton/platforms/windows/Clock.hpp> #include <ableton/platforms/windows/ScanIpIfAddrs.hpp>+#if defined(LINK_WINDOWS_SETTHREADDESCRIPTION) #include <ableton/platforms/windows/ThreadFactory.hpp>+#endif #elif defined(LINK_PLATFORM_MACOSX) #include <ableton/platforms/asio/Context.hpp> #include <ableton/platforms/darwin/Clock.hpp>@@ -46,7 +47,6 @@ #elif defined(ESP_PLATFORM) #include <ableton/platforms/esp32/Clock.hpp> #include <ableton/platforms/esp32/Context.hpp>-#include <ableton/platforms/esp32/Log.hpp> #include <ableton/platforms/esp32/Random.hpp> #include <ableton/platforms/esp32/ScanIpIfAddrs.hpp> #endif@@ -61,36 +61,31 @@ #if defined(LINK_PLATFORM_WINDOWS) using Clock = platforms::windows::Clock; using Random = platforms::stl::Random;-using ThreadPriority = platforms::windows::ThreadPriority; #if defined(LINK_WINDOWS_SETTHREADDESCRIPTION) using IoContext =   platforms::LINK_ASIO_NAMESPACE::Context<platforms::windows::ScanIpIfAddrs,-                                          util::NullLog,-                                          platforms::windows::ThreadFactory>;+    util::NullLog,+    platforms::windows::ThreadFactory>; #else using IoContext =   platforms::LINK_ASIO_NAMESPACE::Context<platforms::windows::ScanIpIfAddrs,-                                          util::NullLog>;+    util::NullLog>; #endif  #elif defined(LINK_PLATFORM_MACOSX) using Clock = platforms::darwin::Clock;-using IoContext =-  platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs,-                                          util::NullLog,-                                          platforms::darwin::ThreadFactory>;+using IoContext = platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs,+  util::NullLog,+  platforms::darwin::ThreadFactory>; using Random = platforms::stl::Random;-using ThreadPriority = platforms::darwin::ThreadPriority;  #elif defined(LINK_PLATFORM_LINUX) using Clock = platforms::linux_::ClockMonotonicRaw; using Random = platforms::stl::Random;-using ThreadPriority = platforms::linux_::ThreadPriority; #ifdef __linux__-using IoContext =-  platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs,-                                          util::NullLog,-                                          platforms::linux_::ThreadFactory>;+using IoContext = platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs,+  util::NullLog,+  platforms::linux_::ThreadFactory>; #else using IoContext =   platforms::LINK_ASIO_NAMESPACE::Context<platforms::posix::ScanIpIfAddrs, util::NullLog>;
link/include/ableton/platforms/asio/AsioTimer.hpp view
@@ -43,7 +43,7 @@ public:   using ErrorCode = ::LINK_ASIO_NAMESPACE::error_code;   using TimePoint = std::chrono::system_clock::time_point;-  using IoService = ::LINK_ASIO_NAMESPACE::io_context;+  using IoService = ::LINK_ASIO_NAMESPACE::io_service;   using SystemTimer = ::LINK_ASIO_NAMESPACE::system_timer;  @@ -82,18 +82,15 @@   template <typename T>   void expires_from_now(T duration)   {-    mpTimer->expires_after(std::move(duration));+    mpTimer->expires_from_now(std::move(duration));   } -  void cancel()+  ErrorCode cancel()   {-    try-    {-      mpTimer->cancel();-    }-    catch (...)-    {-    }+    ErrorCode ec;+    mpTimer->cancel(ec);+    mpAsyncHandler->mpHandler = nullptr;+    return ec;   }    template <typename Handler>@@ -103,7 +100,10 @@     mpTimer->async_wait(util::makeAsyncSafe(mpAsyncHandler));   } -  TimePoint now() const { return std::chrono::system_clock::now(); }+  TimePoint now() const+  {+    return std::chrono::system_clock::now();+  }  private:   struct AsyncHandler
link/include/ableton/platforms/asio/AsioWrapper.hpp view
@@ -36,8 +36,8 @@  #pragma push_macro("ASIO_NO_TYPEID") #define ASIO_NO_TYPEID 1-#define asio link_asio_1_36_0-#define LINK_ASIO_NAMESPACE link_asio_1_36_0+#define asio link_asio_1_28_0+#define LINK_ASIO_NAMESPACE link_asio_1_28_0 #define ASIO_STANDALONE 1 #endif 
link/include/ableton/platforms/asio/Context.hpp view
@@ -23,15 +23,9 @@ #include <ableton/platforms/asio/AsioTimer.hpp> #include <ableton/platforms/asio/LockFreeCallbackDispatcher.hpp> #include <ableton/platforms/asio/Socket.hpp>-#include <memory> #include <thread> #include <utility> -#if defined(__linux__)-#include <netinet/in.h>-#include <sys/socket.h>-#endif- namespace ableton { namespace platforms@@ -65,8 +59,8 @@    template <std::size_t BufferSize>   using Socket = Socket<BufferSize>;-  using IoService = ::LINK_ASIO_NAMESPACE::io_context;-  using Work = ::LINK_ASIO_NAMESPACE::executor_work_guard<IoService::executor_type>;+  using IoService = ::LINK_ASIO_NAMESPACE::io_service;+  using Work = IoService::work;    Context()     : Context(DefaultHandler{})@@ -76,12 +70,10 @@   template <typename ExceptionHandler>   explicit Context(ExceptionHandler exceptHandler)     : mpService(new IoService())-    , mpWork(new Work(mpService->get_executor()))+    , mpWork(new Work(*mpService))   {-    mThread = ThreadFactoryT::makeThread(-      "Link Main",-      [](IoService& service, ExceptionHandler handler)-      {+    mThread = ThreadFactoryT::makeThread("Link Main",+      [](IoService& service, ExceptionHandler handler) {         for (;;)         {           try@@ -95,8 +87,7 @@           }         }       },-      std::ref(*mpService),-      std::move(exceptHandler));+      std::ref(*mpService), std::move(exceptHandler));   }    Context(const Context&) = delete;@@ -131,21 +122,19 @@     template <std::size_t BufferSize>-  Socket<BufferSize> openUnicastSocket(const discovery::IpAddress addr, uint16_t port = 0)+  Socket<BufferSize> openUnicastSocket(const discovery::IpAddress addr)   {     auto socket =       addr.is_v4() ? Socket<BufferSize>{*mpService, ::LINK_ASIO_NAMESPACE::ip::udp::v4()}                    : Socket<BufferSize>{*mpService, ::LINK_ASIO_NAMESPACE::ip::udp::v6()};     socket.mpImpl->mSocket.set_option(       ::LINK_ASIO_NAMESPACE::ip::multicast::enable_loopback(addr.is_loopback()));-    socket.mpImpl->mSocket.set_option(-      ::LINK_ASIO_NAMESPACE::ip::udp::socket::reuse_address(true));     if (addr.is_v4())     {       socket.mpImpl->mSocket.set_option(         ::LINK_ASIO_NAMESPACE::ip::multicast::outbound_interface(addr.to_v4()));       socket.mpImpl->mSocket.bind(-        ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v4(), port});+        ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v4(), 0});     }     else if (addr.is_v6())     {@@ -154,7 +143,7 @@         ::LINK_ASIO_NAMESPACE::ip::multicast::outbound_interface(           static_cast<unsigned int>(scopeId)));       socket.mpImpl->mSocket.bind(-        ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v6(), port});+        ::LINK_ASIO_NAMESPACE::ip::udp::endpoint{addr.to_v6(), 0});     }     else     {@@ -179,22 +168,10 @@      if (addr.is_v4())     {-#if defined(__linux__) && defined(IP_MULTICAST_ALL)-      const int disableAll = 0;-      if (::setsockopt(socket.mpImpl->mSocket.native_handle(),-                       IPPROTO_IP,-                       IP_MULTICAST_ALL,-                       &disableAll,-                       sizeof(disableAll))-          != 0)-      {-        throw std::runtime_error("Failed to set IP_MULTICAST_ALL");-      }-#endif       socket.mpImpl->mSocket.set_option(         ::LINK_ASIO_NAMESPACE::ip::multicast::outbound_interface(addr.to_v4()));       socket.mpImpl->mSocket.bind({::LINK_ASIO_NAMESPACE::ip::address_v4::any(),-                                   discovery::multicastEndpointV4().port()});+        discovery::multicastEndpointV4().port()});       socket.mpImpl->mSocket.set_option(::LINK_ASIO_NAMESPACE::ip::multicast::join_group(         discovery::multicastEndpointV4().address().to_v4(), addr.to_v4()));     }@@ -217,16 +194,25 @@     return socket;   } -  std::vector<discovery::IpAddress> scanNetworkInterfaces() { return mScanIpIfAddrs(); }+  std::vector<discovery::IpAddress> scanNetworkInterfaces()+  {+    return mScanIpIfAddrs();+  } -  Timer makeTimer() const { return {*mpService}; }+  Timer makeTimer() const+  {+    return {*mpService};+  } -  Log& log() { return mLog; }+  Log& log()+  {+    return mLog;+  }    template <typename Handler>   void async(Handler handler)   {-    ::LINK_ASIO_NAMESPACE::post(*mpService, std::move(handler));+    mpService->post(std::move(handler));   }  private:@@ -239,11 +225,13 @@     {     }; -    void operator()(const Exception&) {}+    void operator()(const Exception&)+    {+    }   }; -  std::unique_ptr<IoService> mpService;-  std::unique_ptr<Work> mpWork;+  std::unique_ptr<::LINK_ASIO_NAMESPACE::io_service> mpService;+  std::unique_ptr<::LINK_ASIO_NAMESPACE::io_service::work> mpWork;   std::thread mThread;   Log mLog;   ScanIpIfAddrs mScanIpIfAddrs;
link/include/ableton/platforms/asio/LockFreeCallbackDispatcher.hpp view
@@ -46,33 +46,22 @@     : mCallback(std::move(callback))     , mFallbackPeriod(std::move(fallbackPeriod))     , mRunning(true)+    , mThread(ThreadFactory::makeThread("Link Dispatcher", [this] { run(); }))   {   } -  ~LockFreeCallbackDispatcher() { stop(); }--  void start()+  ~LockFreeCallbackDispatcher()   {-    mThread = ThreadFactory::makeThread("Link Dispatcher", [this] { run(); });+    mRunning = false;+    mCondition.notify_one();+    mThread.join();   } -  void stop()+  void invoke()   {-    const auto wasRunning = mRunning.exchange(false);-    if (!wasRunning)-    {-      return;-    }-     mCondition.notify_one();-    if (mThread.joinable())-    {-      mThread.join();-    }   } -  void invoke() { mCondition.notify_one(); }- private:   void run()   {@@ -82,12 +71,6 @@         std::unique_lock<std::mutex> lock(mMutex);         mCondition.wait_for(lock, mFallbackPeriod);       }--      if (!mRunning.load())-      {-        break;-      }-       mCallback();     }   }
link/include/ableton/platforms/asio/Socket.hpp view
@@ -34,7 +34,7 @@ template <std::size_t MaxPacketSize> struct Socket {-  Socket(::LINK_ASIO_NAMESPACE::io_context& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol)+  Socket(::LINK_ASIO_NAMESPACE::io_service& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol)     : mpImpl(std::make_shared<Impl>(io, protocol))   {   }@@ -47,11 +47,10 @@   {   } -  std::size_t send(const uint8_t* const pData,-                   const size_t numBytes,-                   const discovery::UdpEndpoint& to)+  std::size_t send(+    const uint8_t* const pData, const size_t numBytes, const discovery::UdpEndpoint& to)   {-    assert(numBytes <= MaxPacketSize);+    assert(numBytes < MaxPacketSize);     return mpImpl->mSocket.send_to(::LINK_ASIO_NAMESPACE::buffer(pData, numBytes), to);   } @@ -61,15 +60,17 @@     mpImpl->mHandler = std::move(handler);     mpImpl->mSocket.async_receive_from(       ::LINK_ASIO_NAMESPACE::buffer(mpImpl->mReceiveBuffer, MaxPacketSize),-      mpImpl->mSenderEndpoint,-      util::makeAsyncSafe(mpImpl));+      mpImpl->mSenderEndpoint, util::makeAsyncSafe(mpImpl));   } -  discovery::UdpEndpoint endpoint() const { return mpImpl->mSocket.local_endpoint(); }+  discovery::UdpEndpoint endpoint() const+  {+    return mpImpl->mSocket.local_endpoint();+  }    struct Impl   {-    Impl(::LINK_ASIO_NAMESPACE::io_context& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol)+    Impl(::LINK_ASIO_NAMESPACE::io_service& io, ::LINK_ASIO_NAMESPACE::ip::udp protocol)       : mSocket(io, protocol)     {     }@@ -83,8 +84,8 @@       mSocket.close(ec);     } -    void operator()(const ::LINK_ASIO_NAMESPACE::error_code& error,-                    const std::size_t numBytes)+    void operator()(+      const ::LINK_ASIO_NAMESPACE::error_code& error, const std::size_t numBytes)     {       if (!error && numBytes > 0 && numBytes <= MaxPacketSize)       {
link/include/ableton/platforms/darwin/Clock.hpp view
@@ -55,9 +55,15 @@     return static_cast<Ticks>(micros.count() / mTicksToMicros);   } -  Ticks ticks() const { return mach_absolute_time(); }+  Ticks ticks() const+  {+    return mach_absolute_time();+  } -  std::chrono::microseconds micros() const { return ticksToMicros(ticks()); }+  std::chrono::microseconds micros() const+  {+    return ticksToMicros(ticks());+  }    double mTicksToMicros; };
link/include/ableton/platforms/darwin/ThreadFactory.hpp view
@@ -19,9 +19,6 @@  #pragma once -#include <mach/mach.h>-#include <mach/mach_time.h>-#include <optional> #include <pthread.h> #include <thread> #include <utility>@@ -33,98 +30,16 @@ namespace darwin { -struct ThreadPriority-{-  // Captures the current thread priority and sets the thread priority to high.-  // Noop if there is already a captured priority-  void setHigh()-  {-    if (!moOriginal)-    {-      capture();-    }--    mach_timebase_info_data_t info;-    mach_timebase_info(&info);-    const auto machRatio =-      static_cast<double>(info.denom) / static_cast<double>(info.numer);-    const auto millisecond = machRatio * 1000000;--    struct thread_time_constraint_policy policy;--    // The nominal time interval between the beginnings of two consecutive duty cycles. It-    // defines how often the thread expects to run. A nonzero value specifies the thread's-    // periodicity.-    policy.period =-      static_cast<uint32_t>(millisecond * 1); // link_audio::MainController's timer period--    // The amount of CPU time the thread needs during each period. This is the actual-    // execution time required per cycle. Needs to be less or equal to the period.-    policy.computation = static_cast<uint32_t>(millisecond * 0.2);--    // The maximum real time that may elapse from the start of a period to the end of-    // computation. This sets an upper bound on the allowed delay for completing the-    // computation. It cannot be less than computation.-    policy.constraint = static_cast<uint32_t>(millisecond * 1);--    // A boolean value indicating whether the thread's computation can be interrupted-    // (preempted) by other threads. If set to 1, the thread can be preempted; if 0, it-    // should run to completion within its constraint.-    policy.preemptible = 1;--    thread_policy_set(mach_thread_self(),-                      THREAD_TIME_CONSTRAINT_POLICY,-                      reinterpret_cast<thread_policy_t>(&policy),-                      THREAD_TIME_CONSTRAINT_POLICY_COUNT);-  }--  // Resets the thread priority to the previously captured priority.-  // Noop if there is no captured thread priority-  void reset()-  {-    if (moOriginal)-    {-      thread_policy_set(mach_thread_self(),-                        THREAD_TIME_CONSTRAINT_POLICY,-                        reinterpret_cast<thread_policy_t>(&*moOriginal),-                        THREAD_TIME_CONSTRAINT_POLICY_COUNT);-      moOriginal = std::nullopt;-    }-  }--private:-  void capture()-  {-    thread_time_constraint_policy_data_t policy{};-    mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT;-    boolean_t getDefault = false;-    const auto result = thread_policy_get(mach_thread_self(),-                                          THREAD_TIME_CONSTRAINT_POLICY,-                                          reinterpret_cast<thread_policy_t>(&policy),-                                          &count,-                                          &getDefault);-    if (result == KERN_SUCCESS)-    {-      moOriginal = policy;-    }-  }--  std::optional<thread_time_constraint_policy_data_t> moOriginal;-};- struct ThreadFactory {   template <typename Callable, typename... Args>   static std::thread makeThread(std::string name, Callable&& f, Args&&... args)   {-    return std::thread{[](std::string name, Callable&& f, Args&&... args)-                       {+    return std::thread{[](std::string name, Callable&& f, Args&&... args) {                          pthread_setname_np(name.c_str());                          f(args...);                        },-                       std::move(name),-                       std::forward<Callable>(f),-                       std::forward<Args>(args)...};+      std::move(name), std::forward<Callable>(f), std::forward<Args>(args)...};   } }; 
link/include/ableton/platforms/esp32/Context.hpp view
@@ -24,6 +24,7 @@ #include <ableton/platforms/asio/AsioTimer.hpp> #include <ableton/platforms/asio/Socket.hpp> #include <ableton/platforms/esp32/LockFreeCallbackDispatcher.hpp>+#include <driver/gptimer.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> @@ -39,10 +40,6 @@ {   class ServiceRunner   {-    // This task used to exclusively poll ASIO with `poll_one()`, with an-    // interval of 100 microseconds. Since ASIO uses `select()` internally to-    // implement `poll_one()`, we might as well use an event based approach and-    // save some CPU cycles by using `io_service::run()` instead.     static void run(void* userParams)     {       auto runner = static_cast<ServiceRunner*>(userParams);@@ -50,7 +47,8 @@       {         try         {-          runner->mpService->run();+          ulTaskNotifyTake(pdTRUE, portMAX_DELAY);+          runner->mpService->poll_one();         }         catch (...)         {@@ -58,21 +56,41 @@       }     } +    static void IRAM_ATTR timerIsr(void* userParam)+    {+      static BaseType_t xHigherPriorityTaskWoken = pdFALSE;+      vTaskNotifyGiveFromISR(*((TaskHandle_t*)userParam), &xHigherPriorityTaskWoken);+      if (xHigherPriorityTaskWoken)+      {+        portYIELD_FROM_ISR();+      }+    }+   public:     ServiceRunner()       : mpService(new ::asio::io_service())       , mpWork(new ::asio::io_service::work(*mpService))     {-      xTaskCreatePinnedToCore(run,-                              "link",-                              8192,-                              this,-                              2 | portPRIVILEGE_BIT,-                              &mTaskHandle,-                              LINK_ESP_TASK_CORE_ID);+      xTaskCreatePinnedToCore(run, "link", 8192, this, 2 | portPRIVILEGE_BIT,+        &mTaskHandle, LINK_ESP_TASK_CORE_ID);++      const esp_timer_create_args_t timerArgs = {+        .callback = &timerIsr,+        .arg = (void*)&mTaskHandle,+        .dispatch_method = ESP_TIMER_TASK,+        .name = "link",+        .skip_unhandled_events = true,+      };++      ESP_ERROR_CHECK(esp_timer_create(&timerArgs, &mTimer));+      ESP_ERROR_CHECK(esp_timer_start_periodic(mTimer, 100));     } -    ~ServiceRunner() { vTaskDelete(mTaskHandle); }+    ~ServiceRunner()+    {+      esp_timer_delete(mTimer);+      vTaskDelete(mTaskHandle);+    }      template <typename Handler>     void async(Handler handler)@@ -80,10 +98,14 @@       mpService->post(std::move(handler));     } -    ::asio::io_service& service() const { return *mpService; }+    ::asio::io_service& service() const+    {+      return *mpService;+    }    private:     TaskHandle_t mTaskHandle;+    esp_timer_handle_t mTimer;     std::unique_ptr<::asio::io_service> mpService;     std::unique_ptr<::asio::io_service::work> mpWork;   };@@ -116,7 +138,9 @@   {   } -  void stop() {}+  void stop()+  {+  }    template <std::size_t BufferSize>   Socket<BufferSize> openUnicastSocket(const ::asio::ip::address& addr)@@ -188,11 +212,20 @@     return socket;   } -  std::vector<::asio::ip::address> scanNetworkInterfaces() { return mScanIpIfAddrs(); }+  std::vector<::asio::ip::address> scanNetworkInterfaces()+  {+    return mScanIpIfAddrs();+  } -  Timer makeTimer() const { return {serviceRunner().service()}; }+  Timer makeTimer() const+  {+    return {serviceRunner().service()};+  } -  Log& log() { return mLog; }+  Log& log()+  {+    return mLog;+  }    template <typename Handler>   void async(Handler handler)@@ -210,7 +243,9 @@     {     }; -    void operator()(const Exception&) {}+    void operator()(const Exception&)+    {+    }   };    static ServiceRunner& serviceRunner()
link/include/ableton/platforms/esp32/LockFreeCallbackDispatcher.hpp view
@@ -47,20 +47,12 @@     , mFallbackPeriod(std::move(fallbackPeriod))     , mRunning(true)   {+    xTaskCreate(run, "link", 4096, this, tskIDLE_PRIORITY, &mTaskHandle);   } -  ~LockFreeCallbackDispatcher() { stop(); }--  void start() { xTaskCreate(run, "link", 4096, this, tskIDLE_PRIORITY, &mTaskHandle); }--  void stop()+  ~LockFreeCallbackDispatcher()   {-    const auto wasRunning = mRunning.exchange(false);-    if (!wasRunning)-    {-      return;-    }-+    mRunning = false;     mCondition.notify_one();     vTaskDelete(mTaskHandle);   }@@ -84,12 +76,6 @@         std::unique_lock<std::mutex> lock(dispatcher->mMutex);         dispatcher->mCondition.wait_for(lock, dispatcher->mFallbackPeriod);       }--      if (!dispatcher->mRunning.load())-      {-        break;-      }-       dispatcher->mCallback();       vTaskDelay(1);     }
− link/include/ableton/platforms/esp32/Log.hpp
@@ -1,138 +0,0 @@-/* Copyright 2025, All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- */--#pragma once--#include <esp_log.h>-#include <sstream>-#include <string>--namespace ableton-{-namespace platforms-{-namespace esp32-{--// ESP-IDF logging implementation for Ableton Link-struct EspLog-{-  enum class Level-  {-    Debug,-    Info,-    Warning,-    Error-  };--  // Tag used for all Link logging-  //-  // All Link logging should go through this tag, since ESP-IDF has a lot of-  // internal logging and this helps to manage being able to filter.-  //-  // ESP-IDF has no wildcard filtering support, so for channels we prepend the-  // channel name to the message text, since channels can be created based on-  // dynamic data, like IP addresses.-  static constexpr const char* kTag = "ableton_link";--  EspLog() = default;--  explicit EspLog(std::string context)-    : mContext(std::move(context))-  {-  }--  struct EspLogStream-  {-    EspLogStream(Level level, const std::string& context)-      : mLevel(level)-      , mContext(context)-    {-    }--    EspLogStream(EspLogStream&& rhs)-      : mLevel(rhs.mLevel)-      , mContext(rhs.mContext)-      , mStream(std::move(rhs.mStream))-    {-      rhs.mMoved = true;-    }--    ~EspLogStream()-    {-      if (!mMoved)-      {-        std::string msg = mStream.str();-        // Prepend context to message if present-        if (!mContext.empty())-        {-          msg = "[" + mContext + "] " + msg;-        }-        switch (mLevel)-        {-        case Level::Debug:-          ESP_LOGD(kTag, "%s", msg.c_str());-          break;-        case Level::Info:-          ESP_LOGI(kTag, "%s", msg.c_str());-          break;-        case Level::Warning:-          ESP_LOGW(kTag, "%s", msg.c_str());-          break;-        case Level::Error:-          ESP_LOGE(kTag, "%s", msg.c_str());-          break;-        }-      }-    }--    template <typename T>-    EspLogStream& operator<<(const T& rhs)-    {-      mStream << rhs;-      return *this;-    }--    Level mLevel;-    const std::string& mContext;-    std::ostringstream mStream;-    bool mMoved = false;-  };--  friend EspLogStream debug(const EspLog& log) { return {Level::Debug, log.mContext}; }--  friend EspLogStream info(const EspLog& log) { return {Level::Info, log.mContext}; }--  friend EspLogStream warning(const EspLog& log)-  {-    return {Level::Warning, log.mContext};-  }--  friend EspLogStream error(const EspLog& log) { return {Level::Error, log.mContext}; }--  friend EspLog channel(const EspLog& log, const std::string& channelName)-  {-    auto newContext =-      log.mContext.empty() ? channelName : log.mContext + "::" + channelName;-    return EspLog{std::move(newContext)};-  }--  std::string mContext;-};--} // namespace esp32-} // namespace platforms-} // namespace ableton
link/include/ableton/platforms/esp32/ScanIpIfAddrs.hpp view
@@ -19,17 +19,10 @@  #include <ableton/discovery/AsioTypes.hpp> #include <arpa/inet.h>-#include <esp_idf_version.h> #include <esp_netif.h> #include <net/if.h> #include <vector> -// esp_netif_next_unsafe() was introduced in ESP-IDF v5.5 as a rename of-// esp_netif_next() to make the thread-unsafety explicit.-#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0)-#define esp_netif_next_unsafe esp_netif_next-#endif- namespace ableton { namespace platforms@@ -37,36 +30,26 @@ namespace esp32 { -// ESP32 implementation of ip interface address scanner.-// Uses esp_netif_tcpip_exec() to iterate network interfaces safely from-// the TCPIP thread, where the interface list is guaranteed stable.-// esp_netif_tcpip_exec() is available in ESP-IDF v5.3 and later.+// ESP32 implementation of ip interface address scanner struct ScanIpIfAddrs {   std::vector<discovery::IpAddress> operator()()   {     std::vector<discovery::IpAddress> addrs;-    esp_netif_tcpip_exec(-      [](void* ctx) -> esp_err_t+    // Get first network interface+    esp_netif_t* esp_netif = esp_netif_next(NULL);+    while (esp_netif)+    {+      // Check if interface is active+      if (esp_netif_is_netif_up(esp_netif))       {-        auto& out = *static_cast<std::vector<discovery::IpAddress>*>(ctx);-        // Get first network interface-        esp_netif_t* esp_netif = esp_netif_next_unsafe(NULL);-        while (esp_netif)-        {-          // Check if interface is active-          if (esp_netif_is_netif_up(esp_netif))-          {-            esp_netif_ip_info_t ip_info;-            esp_netif_get_ip_info(esp_netif, &ip_info);-            out.emplace_back(::asio::ip::address_v4(ntohl(ip_info.ip.addr)));-          }-          // Get next network interface-          esp_netif = esp_netif_next_unsafe(esp_netif);-        }-        return ESP_OK;-      },-      &addrs);+        esp_netif_ip_info_t ip_info;+        esp_netif_get_ip_info(esp_netif, &ip_info);+        addrs.emplace_back(::asio::ip::address_v4(ntohl(ip_info.ip.addr)));+      }+      // Get next network interface+      esp_netif = esp_netif_next(esp_netif);+    }     return addrs;   } };
link/include/ableton/platforms/linux/ThreadFactory.hpp view
@@ -19,10 +19,8 @@  #pragma once -#include <optional> #include <pthread.h> #include <thread>-#include <utility>  namespace ableton {@@ -30,44 +28,6 @@ { namespace linux_ {--struct ThreadPriority-{-  void setHigh()-  {-    if (!moOriginal)-    {-      capture();-    }--    sched_param high{};-    high.sched_priority = 35;-    pthread_setschedparam(pthread_self(), SCHED_FIFO, &high);-  }--  void reset()-  {-    if (moOriginal)-    {-      pthread_setschedparam(pthread_self(), moOriginal->first, &moOriginal->second);-      moOriginal = std::nullopt;-    }-  }--private:-  void capture()-  {-    int policy;-    sched_param params;-    const auto result = pthread_getschedparam(pthread_self(), &policy, &params);-    if (result == 0)-    {-      moOriginal = std::make_pair(policy, params);-    }-  }--  std::optional<std::pair<int, sched_param>> moOriginal;-};  struct ThreadFactory {
link/include/ableton/platforms/posix/ScanIpIfAddrs.hpp view
@@ -82,49 +82,43 @@     std::map<std::string, discovery::IpAddress> IpInterfaceNames;      detail::GetIfAddrs getIfAddrs;-    getIfAddrs.withIfAddrs(-      [&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces)+    getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) {+      const struct ifaddrs* interface;+      for (interface = &interfaces; interface; interface = interface->ifa_next)       {-        const struct ifaddrs* interface;-        for (interface = &interfaces; interface; interface = interface->ifa_next)+        const auto addr =+          reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr);+        if (addr && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET)         {-          const auto addr =-            reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr);-          if (addr && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET)-          {-            const auto bytes = reinterpret_cast<const char*>(&addr->sin_addr);-            const auto address =-              discovery::makeAddressFromBytes<discovery::IpAddressV4>(bytes);-            addrs.emplace_back(address);-            IpInterfaceNames.insert(std::make_pair(interface->ifa_name, address));-          }+          const auto bytes = reinterpret_cast<const char*>(&addr->sin_addr);+          const auto address = discovery::makeAddress<discovery::IpAddressV4>(bytes);+          addrs.emplace_back(address);+          IpInterfaceNames.insert(std::make_pair(interface->ifa_name, address));         }-      });+      }+    }); -    // Add IPv6 addresses as backup in case multicast on IPv4 fails-    getIfAddrs.withIfAddrs(-      [&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces)+    getIfAddrs.withIfAddrs([&addrs, &IpInterfaceNames](const struct ifaddrs& interfaces) {+      const struct ifaddrs* interface;+      for (interface = &interfaces; interface; interface = interface->ifa_next)       {-        const struct ifaddrs* interface;-        for (interface = &interfaces; interface; interface = interface->ifa_next)+        const auto addr =+          reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr);+        if (IpInterfaceNames.find(interface->ifa_name) != IpInterfaceNames.end() && addr+            && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET6)         {-          const auto addr =-            reinterpret_cast<const struct sockaddr_in*>(interface->ifa_addr);-          if (IpInterfaceNames.find(interface->ifa_name) != IpInterfaceNames.end() && addr-              && interface->ifa_flags & IFF_RUNNING && addr->sin_family == AF_INET6)+          const auto addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr);+          const auto bytes = reinterpret_cast<const char*>(&addr6->sin6_addr);+          const auto scopeId = addr6->sin6_scope_id;+          const auto address =+            discovery::makeAddress<discovery::IpAddressV6>(bytes, scopeId);+          if (!address.is_loopback() && address.is_link_local())           {-            const auto addr6 = reinterpret_cast<const struct sockaddr_in6*>(addr);-            const auto bytes = reinterpret_cast<const char*>(&addr6->sin6_addr);-            const auto scopeId = addr6->sin6_scope_id;-            const auto address =-              discovery::makeAddressFromBytes<discovery::IpAddressV6>(bytes, scopeId);-            if (!address.is_loopback() && address.is_link_local())-            {-              addrs.emplace_back(address);-            }+            addrs.emplace_back(address);           }         }-      });+      }+    });      return addrs;   };
link/include/ableton/platforms/stl/Random.hpp view
@@ -36,7 +36,10 @@   {   } -  uint8_t operator()() { return static_cast<uint8_t>(dist(gen)); }+  uint8_t operator()()+  {+    return static_cast<uint8_t>(dist(gen));+  }    std::random_device rd;   std::mt19937 gen;
link/include/ableton/platforms/windows/Clock.hpp view
@@ -58,7 +58,10 @@     return count.QuadPart;   } -  std::chrono::microseconds micros() const { return ticksToMicros(ticks()); }+  std::chrono::microseconds micros() const+  {+    return ticksToMicros(ticks());+  }    double mTicksToMicros; };
link/include/ableton/platforms/windows/ScanIpIfAddrs.hpp view
@@ -54,13 +54,10 @@       adapter_addrs = (IP_ADAPTER_ADDRESSES*)malloc(adapter_addrs_buffer_size);       assert(adapter_addrs); -      DWORD error =-        ::GetAdaptersAddresses(AF_UNSPEC,-                               GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST-                                 | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME,-                               NULL,-                               adapter_addrs,-                               &adapter_addrs_buffer_size);+      DWORD error = ::GetAdaptersAddresses(AF_UNSPEC,+        GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER+          | GAA_FLAG_SKIP_FRIENDLY_NAME,+        NULL, adapter_addrs, &adapter_addrs_buffer_size);        if (error == ERROR_SUCCESS)       {@@ -109,67 +106,58 @@     std::map<std::string, discovery::IpAddress> IpInterfaceNames;      detail::GetIfAddrs getIfAddrs;-    getIfAddrs.withIfAddrs(-      [&](const IP_ADAPTER_ADDRESSES& interfaces)+    getIfAddrs.withIfAddrs([&](const IP_ADAPTER_ADDRESSES& interfaces) {+      const IP_ADAPTER_ADDRESSES* networkInterface;+      for (networkInterface = &interfaces; networkInterface;+           networkInterface = networkInterface->Next)       {-        const IP_ADAPTER_ADDRESSES* networkInterface;-        for (networkInterface = &interfaces; networkInterface;-             networkInterface = networkInterface->Next)+        for (IP_ADAPTER_UNICAST_ADDRESS* address = networkInterface->FirstUnicastAddress;+             NULL != address; address = address->Next)         {-          for (IP_ADAPTER_UNICAST_ADDRESS* address =-                 networkInterface->FirstUnicastAddress;-               NULL != address;-               address = address->Next)+          auto family = address->Address.lpSockaddr->sa_family;+          if (AF_INET == family)           {-            auto family = address->Address.lpSockaddr->sa_family;-            if (AF_INET == family)-            {-              // IPv4-              SOCKADDR_IN* addr4 =-                reinterpret_cast<SOCKADDR_IN*>(address->Address.lpSockaddr);-              const auto bytes = reinterpret_cast<const char*>(&addr4->sin_addr);-              const auto ipv4address =-                discovery::makeAddressFromBytes<discovery::IpAddressV4>(bytes);-              addrs.emplace_back(ipv4address);-              IpInterfaceNames.insert(-                std::make_pair(networkInterface->AdapterName, ipv4address));-            }+            // IPv4+            SOCKADDR_IN* addr4 =+              reinterpret_cast<SOCKADDR_IN*>(address->Address.lpSockaddr);+            const auto bytes = reinterpret_cast<const char*>(&addr4->sin_addr);+            const auto ipv4address =+              discovery::makeAddress<discovery::IpAddressV4>(bytes);+            addrs.emplace_back(ipv4address);+            IpInterfaceNames.insert(+              std::make_pair(networkInterface->AdapterName, ipv4address));           }         }-      });+      }+    }); -    // Add IPv6 addresses as backup in case multicast on IPv4 fails-    getIfAddrs.withIfAddrs(-      [&](const IP_ADAPTER_ADDRESSES& interfaces)+    getIfAddrs.withIfAddrs([&](const IP_ADAPTER_ADDRESSES& interfaces) {+      const IP_ADAPTER_ADDRESSES* networkInterface;+      for (networkInterface = &interfaces; networkInterface;+           networkInterface = networkInterface->Next)       {-        const IP_ADAPTER_ADDRESSES* networkInterface;-        for (networkInterface = &interfaces; networkInterface;-             networkInterface = networkInterface->Next)+        for (IP_ADAPTER_UNICAST_ADDRESS* address = networkInterface->FirstUnicastAddress;+             NULL != address; address = address->Next)         {-          for (IP_ADAPTER_UNICAST_ADDRESS* address =-                 networkInterface->FirstUnicastAddress;-               NULL != address;-               address = address->Next)+          auto family = address->Address.lpSockaddr->sa_family;+          if (AF_INET6 == family+              && IpInterfaceNames.find(networkInterface->AdapterName)+                   != IpInterfaceNames.end())           {-            auto family = address->Address.lpSockaddr->sa_family;-            if (AF_INET6 == family-                && IpInterfaceNames.find(networkInterface->AdapterName)-                     != IpInterfaceNames.end())+            SOCKADDR_IN6* sockAddr =+              reinterpret_cast<SOCKADDR_IN6*>(address->Address.lpSockaddr);+            const auto scopeId = sockAddr->sin6_scope_id;+            const auto bytes = reinterpret_cast<const char*>(&sockAddr->sin6_addr);+            const auto addr6 =+              discovery::makeAddress<discovery::IpAddressV6>(bytes, scopeId);+            if (!addr6.is_loopback() && addr6.is_link_local())             {-              SOCKADDR_IN6* sockAddr =-                reinterpret_cast<SOCKADDR_IN6*>(address->Address.lpSockaddr);-              const auto scopeId = sockAddr->sin6_scope_id;-              const auto bytes = reinterpret_cast<const char*>(&sockAddr->sin6_addr);-              const auto addr6 =-                discovery::makeAddressFromBytes<discovery::IpAddressV6>(bytes, scopeId);-              if (!addr6.is_loopback() && addr6.is_link_local())-              {-                addrs.emplace_back(addr6);-              }+              addrs.emplace_back(addr6);             }           }         }-      });+      }+    });      return addrs;   }
link/include/ableton/platforms/windows/ThreadFactory.hpp view
@@ -19,9 +19,6 @@  #pragma once -#include <Windows.h>-#include <avrt.h>-#include <optional> #include <processthreadsapi.h> #include <thread> #include <utility>@@ -33,54 +30,20 @@ namespace windows { -struct ThreadPriority-{-  void setHigh()-  {-    if (moOriginal)-    {-      return;-    }--    DWORD taskIndex = 0;-    HANDLE handle = ::AvSetMmThreadCharacteristicsW(L"Distribution", &taskIndex);-    if (handle)-    {-      ::AvSetMmThreadPriority(handle, AVRT_PRIORITY_HIGH);-      moOriginal = handle;-    }-  }--  void reset()-  {-    if (moOriginal)-    {-      ::AvRevertMmThreadCharacteristics(*moOriginal);-      moOriginal = std::nullopt;-    }-  }--private:-  std::optional<HANDLE> moOriginal;-};- struct ThreadFactory {   template <typename Callable, typename... Args>   static std::thread makeThread(std::string name, Callable&& f, Args&&... args)   {     return std::thread(-      [](std::string name, Callable&& f, Args&&... args)-      {+      [](std::string name, Callable&& f, Args&&... args) {         assert(name.length() < 20);         wchar_t nativeName[20];         mbstowcs(nativeName, name.c_str(), name.length() + 1);         SetThreadDescription(GetCurrentThread(), nativeName);         f(args...);       },-      std::move(name),-      std::forward<Callable>(f),-      std::forward<Args>(args)...);+      std::move(name), std::forward<Callable>(f), std::forward<Args>(args)...);   } }; 
link/include/ableton/platforms/windows/Windows.hpp view
@@ -26,7 +26,7 @@ #define htonll(x) (x) #define ntohll(x) (x) #else-#define htonll(x) (((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))-#define ntohll(x) (((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))+#define htonll(x) (((uint64_t)htonl((x)&0xFFFFFFFF) << 32) | htonl((x) >> 32))+#define ntohll(x) (((uint64_t)ntohl((x)&0xFFFFFFFF) << 32) | ntohl((x) >> 32)) #endif #endif
link/include/ableton/test/serial_io/Context.hpp view
@@ -37,8 +37,8 @@ { public:   Context(const SchedulerTree::TimePoint& now,-          const std::vector<discovery::IpAddress>& ifAddrs,-          std::shared_ptr<SchedulerTree> pScheduler)+    const std::vector<discovery::IpAddress>& ifAddrs,+    std::shared_ptr<SchedulerTree> pScheduler)     : mNow(now)     , mIfAddrs(ifAddrs)     , mpScheduler(std::move(pScheduler))@@ -67,7 +67,9 @@   {   } -  void stop() {}+  void stop()+  {+  }    template <typename Handler>   void async(Handler handler)@@ -77,13 +79,22 @@    using Timer = serial_io::Timer; -  Timer makeTimer() { return {mNextTimerId++, mNow, mpScheduler}; }+  Timer makeTimer()+  {+    return {mNextTimerId++, mNow, mpScheduler};+  }    using Log = util::NullLog; -  Log& log() { return mLog; }+  Log& log()+  {+    return mLog;+  } -  std::vector<discovery::IpAddress> scanNetworkInterfaces() { return mIfAddrs; }+  std::vector<discovery::IpAddress> scanNetworkInterfaces()+  {+    return mIfAddrs;+  }  private:   const SchedulerTree::TimePoint& mNow;
link/include/ableton/test/serial_io/Fixture.hpp view
@@ -40,7 +40,10 @@   {   } -  ~Fixture() { flush(); }+  ~Fixture()+  {+    flush();+  }    Fixture(const Fixture&) = delete;   Fixture& operator=(const Fixture&) = delete;@@ -52,9 +55,15 @@     mIfAddrs = std::move(ifAddrs);   } -  Context makeIoContext() { return {mNow, mIfAddrs, mpScheduler}; }+  Context makeIoContext()+  {+    return {mNow, mIfAddrs, mpScheduler};+  } -  void flush() { mpScheduler->run(); }+  void flush()+  {+    mpScheduler->run();+  }    template <typename T, typename Rep>   void advanceTime(std::chrono::duration<T, Rep> duration)
link/include/ableton/test/serial_io/Timer.hpp view
@@ -34,8 +34,8 @@   using TimePoint = SchedulerTree::TimePoint;    Timer(const SchedulerTree::TimerId timerId,-        const TimePoint& now,-        std::shared_ptr<SchedulerTree> pScheduler)+    const TimePoint& now,+    std::shared_ptr<SchedulerTree> pScheduler)     : mId(timerId)     , mNow(now)     , mpScheduler(std::move(pScheduler))@@ -93,7 +93,10 @@     pScheduler->setTimer(mId, mExpiration, std::move(handler));   } -  TimePoint now() const { return mNow; }+  TimePoint now() const+  {+    return mNow;+  }    const SchedulerTree::TimerId mId;   const TimePoint& mNow;
− link/include/ableton/util/FloatIntConversion.hpp
@@ -1,54 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */---#pragma once--#include <algorithm>-#include <cmath>-#include <cstdint>-#include <limits>--namespace ableton-{-namespace util-{--template <typename T>-int16_t floatToInt16(const T src)-{-  static_assert(std::is_same<T, float>::value || std::is_same<T, double>::value);--  constexpr auto kScale = std::numeric_limits<int16_t>::max() + 1;-  constexpr auto kMin = T{-1};-  constexpr auto kMax = T{1} - T{1} / kScale;-  return int16_t(std::round(kScale * std::clamp(src, kMin, kMax)));-}--template <typename T>-T int16ToFloat(const int16_t src)-{-  static_assert(std::is_same<T, float>::value || std::is_same<T, double>::value);--  constexpr auto kScale = std::numeric_limits<int16_t>::max() + 1;-  return static_cast<T>(src) / kScale;-}--} // namespace util-} // namespace ableton
link/include/ableton/util/Injected.hpp view
@@ -55,13 +55,25 @@     return *this;   } -  T* operator->() { return &val; }+  T* operator->()+  {+    return &val;+  } -  const T* operator->() const { return &val; }+  const T* operator->() const+  {+    return &val;+  } -  T& operator*() { return val; }+  T& operator*()+  {+    return val;+  } -  const T& operator*() const { return val; }+  const T& operator*() const+  {+    return val;+  }    T val; };@@ -98,13 +110,25 @@     return *this;   } -  T* operator->() { return &ref.get(); }+  T* operator->()+  {+    return &ref.get();+  } -  const T* operator->() const { return &ref.get(); }+  const T* operator->() const+  {+    return &ref.get();+  } -  T& operator*() { return ref; }+  T& operator*()+  {+    return ref;+  } -  const T& operator*() const { return ref; }+  const T& operator*() const+  {+    return ref;+  }    std::reference_wrapper<T> ref; };@@ -141,13 +165,25 @@     return *this;   } -  T* operator->() { return shared.get(); }+  T* operator->()+  {+    return shared.get();+  } -  const T* operator->() const { return shared.get(); }+  const T* operator->() const+  {+    return shared.get();+  } -  T& operator*() { return *shared; }+  T& operator*()+  {+    return *shared;+  } -  const T& operator*() const { return *shared; }+  const T& operator*() const+  {+    return *shared;+  }    std::shared_ptr<T> shared; };@@ -184,13 +220,25 @@     return *this;   } -  T* operator->() { return unique.get(); }+  T* operator->()+  {+    return unique.get();+  } -  const T* operator->() const { return unique.get(); }+  const T* operator->() const+  {+    return unique.get();+  } -  T& operator*() { return *unique; }+  T& operator*()+  {+    return *unique;+  } -  const T& operator*() const { return *unique; }+  const T& operator*() const+  {+    return *unique;+  }    std::unique_ptr<T> unique; };
− link/include/ableton/util/Locked.hpp
@@ -1,58 +0,0 @@-/* Copyright 2025, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */---#pragma once--#include <mutex>--namespace ableton-{-namespace util-{--template <typename T>-struct Locked-{-public:-  Locked(const T& val)-    : mVal(val)-  {-  }--  T read() const-  {-    std::lock_guard lock(mMutex);-    return mVal;-  }--  template <typename Handler>-  void update(Handler handler)-  {-    std::lock_guard lock(mMutex);-    handler(mVal);-  }--private:-  T mVal;-  mutable std::mutex mMutex;-};--} // namespace util-} // namespace ableton
link/include/ableton/util/Log.hpp view
@@ -20,15 +20,30 @@     return log;   } -  friend const NullLog& debug(const NullLog& log) { return log; }+  friend const NullLog& debug(const NullLog& log)+  {+    return log;+  } -  friend const NullLog& info(const NullLog& log) { return log; }+  friend const NullLog& info(const NullLog& log)+  {+    return log;+  } -  friend const NullLog& warning(const NullLog& log) { return log; }+  friend const NullLog& warning(const NullLog& log)+  {+    return log;+  } -  friend const NullLog& error(const NullLog& log) { return log; }+  friend const NullLog& error(const NullLog& log)+  {+    return log;+  } -  friend NullLog channel(const NullLog&, std::string) { return {}; }+  friend NullLog channel(const NullLog&, std::string)+  {+    return {};+  } };  // std streams-based log@@ -75,13 +90,25 @@     const std::string& mChannelName;   }; -  friend StdLogStream debug(const StdLog& log) { return {std::clog, log.mChannelName}; }+  friend StdLogStream debug(const StdLog& log)+  {+    return {std::clog, log.mChannelName};+  } -  friend StdLogStream info(const StdLog& log) { return {std::clog, log.mChannelName}; }+  friend StdLogStream info(const StdLog& log)+  {+    return {std::clog, log.mChannelName};+  } -  friend StdLogStream warning(const StdLog& log) { return {std::clog, log.mChannelName}; }+  friend StdLogStream warning(const StdLog& log)+  {+    return {std::clog, log.mChannelName};+  } -  friend StdLogStream error(const StdLog& log) { return {std::cerr, log.mChannelName}; }+  friend StdLogStream error(const StdLog& log)+  {+    return {std::cerr, log.mChannelName};+  }    friend StdLog channel(const StdLog& log, const std::string& channelName)   {
− link/include/ableton/util/TripleBuffer.hpp
@@ -1,117 +0,0 @@-/* Copyright 2022, Ableton AG, Berlin. All rights reserved.- *- *  This program is free software: you can redistribute it and/or modify- *  it under the terms of the GNU General Public License as published by- *  the Free Software Foundation, either version 2 of the License, or- *  (at your option) any later version.- *- *  This program is distributed in the hope that it will be useful,- *  but WITHOUT ANY WARRANTY; without even the implied warranty of- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- *  GNU General Public License for more details.- *- *  You should have received a copy of the GNU General Public License- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.- *- *  If you would like to incorporate Link into a proprietary software application,- *  please contact <link-devs@ableton.com>.- */---#pragma once--#include <array>-#include <atomic>-#include <cassert>-#include <cstdint>-#include <optional>--namespace ableton-{-namespace util-{--template <typename T>-struct TripleBuffer-{-public:-  TripleBuffer()-    : mBuffers{{{}, {}, {}}}-  {-    assert(mState.is_lock_free());-  }--  explicit TripleBuffer(const T& initial)-    : mBuffers{{initial, initial, initial}}-  {-    assert(mState.is_lock_free());-  }--  TripleBuffer(const TripleBuffer&) = delete;-  TripleBuffer& operator=(const TripleBuffer&) = delete;--  T read() noexcept-  {-    loadReadBuffer();-    return mBuffers[mReadIndex];-  }--  std::optional<T> readNew()-  {-    if (loadReadBuffer())-    {-      return std::optional<T>(mBuffers[mReadIndex]);-    }-    return std::nullopt;-  }--  template <typename U>-  void write(U&& value)-  {-    mBuffers[mWriteIndex] = std::forward<U>(value);--    const auto prevState =-      mState.exchange(makeState(mWriteIndex, true), std::memory_order_acq_rel);--    mWriteIndex = backIndex(prevState);-  }--private:-  bool loadReadBuffer()-  {-    auto state = mState.load(std::memory_order_acquire);-    auto isNew = isNewWrite(state);-    if (isNew)-    {-      const auto prevState =-        mState.exchange(makeState(mReadIndex, false), std::memory_order_acq_rel);--      mReadIndex = backIndex(prevState);-    }-    return isNew;-  }--  using BackingState = uint32_t;--  static constexpr bool isNewWrite(const BackingState state)-  {-    return (state & 0x0000FFFFu) != 0;-  }--  static constexpr uint32_t backIndex(const BackingState state) { return state >> 16; }--  static constexpr BackingState makeState(const uint32_t backBufferIndex,-                                          const bool isWrite)-  {-    return (backBufferIndex << 16) | uint32_t(isWrite);-  }--  std::atomic<BackingState> mState{makeState(1u, false)}; // Reader and writer-  uint32_t mReadIndex = 0u;                               // Reader only-  uint32_t mWriteIndex = 2u;                              // Writer only--  std::array<T, 3> mBuffers{};-};--} // namespace util-} // namespace ableton
link/include/ableton/util/test/IoService.hpp view
@@ -41,7 +41,10 @@     {     } -    void expires_at(std::chrono::system_clock::time_point t) { mpTimer->expires_at(t); }+    void expires_at(std::chrono::system_clock::time_point t)+    {+      mpTimer->expires_at(t);+    }      template <typename T, typename Rep>     void expires_from_now(std::chrono::duration<T, Rep> duration)@@ -49,7 +52,10 @@       mpTimer->expires_from_now(duration);     } -    ErrorCode cancel() { return mpTimer->cancel(); }+    ErrorCode cancel()+    {+      return mpTimer->cancel();+    }      template <typename Handler>     void async_wait(Handler handler)@@ -57,7 +63,10 @@       mpTimer->async_wait(std::move(handler));     } -    TimePoint now() const { return mpTimer->now(); }+    TimePoint now() const+    {+      return mpTimer->now();+    }      util::test::Timer* mpTimer;   };
link/include/ableton/util/test/Timer.hpp view
@@ -70,7 +70,10 @@     mHandler = [handler](ErrorCode ec) { handler(ec); };   } -  std::chrono::system_clock::time_point now() const { return mNow; }+  std::chrono::system_clock::time_point now() const+  {+    return mNow;+  }    template <typename T, typename Rep>   void advance(std::chrono::duration<T, Rep> duration)
link/modules/asio-standalone/asio/include/asio.hpp view
@@ -2,7 +2,7 @@ // asio.hpp // ~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -28,6 +28,7 @@ #include "asio/async_result.hpp" #include "asio/awaitable.hpp" #include "asio/basic_datagram_socket.hpp"+#include "asio/basic_deadline_timer.hpp" #include "asio/basic_file.hpp" #include "asio/basic_io_object.hpp" #include "asio/basic_random_access_file.hpp"@@ -58,27 +59,21 @@ #include "asio/buffered_write_stream_fwd.hpp" #include "asio/buffered_write_stream.hpp" #include "asio/buffers_iterator.hpp"-#include "asio/cancel_after.hpp"-#include "asio/cancel_at.hpp" #include "asio/cancellation_signal.hpp" #include "asio/cancellation_state.hpp" #include "asio/cancellation_type.hpp"-#include "asio/co_composed.hpp" #include "asio/co_spawn.hpp" #include "asio/completion_condition.hpp" #include "asio/compose.hpp"-#include "asio/composed.hpp"-#include "asio/config.hpp" #include "asio/connect.hpp" #include "asio/connect_pipe.hpp" #include "asio/consign.hpp" #include "asio/coroutine.hpp"+#include "asio/deadline_timer.hpp" #include "asio/defer.hpp" #include "asio/deferred.hpp"-#include "asio/default_completion_token.hpp" #include "asio/detached.hpp" #include "asio/dispatch.hpp"-#include "asio/disposition.hpp" #include "asio/error.hpp" #include "asio/error_code.hpp" #include "asio/execution.hpp"@@ -86,15 +81,30 @@ #include "asio/execution/any_executor.hpp" #include "asio/execution/blocking.hpp" #include "asio/execution/blocking_adaptation.hpp"+#include "asio/execution/bulk_execute.hpp"+#include "asio/execution/bulk_guarantee.hpp"+#include "asio/execution/connect.hpp" #include "asio/execution/context.hpp" #include "asio/execution/context_as.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/invocable_archetype.hpp" #include "asio/execution/mapping.hpp" #include "asio/execution/occupancy.hpp"+#include "asio/execution/operation_state.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/execution/prefer_only.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/receiver_invocation_error.hpp" #include "asio/execution/relationship.hpp"+#include "asio/execution/schedule.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"+#include "asio/execution/start.hpp"+#include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/executor_work_guard.hpp" #include "asio/file_base.hpp"@@ -103,11 +113,14 @@ #include "asio/generic/raw_protocol.hpp" #include "asio/generic/seq_packet_protocol.hpp" #include "asio/generic/stream_protocol.hpp"+#include "asio/handler_alloc_hook.hpp" #include "asio/handler_continuation_hook.hpp"+#include "asio/handler_invoke_hook.hpp" #include "asio/high_resolution_timer.hpp"-#include "asio/immediate.hpp" #include "asio/io_context.hpp" #include "asio/io_context_strand.hpp"+#include "asio/io_service.hpp"+#include "asio/io_service_strand.hpp" #include "asio/ip/address.hpp" #include "asio/ip/address_v4.hpp" #include "asio/ip/address_v4_iterator.hpp"@@ -181,6 +194,7 @@ #include "asio/this_coro.hpp" #include "asio/thread.hpp" #include "asio/thread_pool.hpp"+#include "asio/time_traits.hpp" #include "asio/use_awaitable.hpp" #include "asio/use_future.hpp" #include "asio/uses_executor.hpp"
link/modules/asio-standalone/asio/include/asio/any_completion_executor.hpp view
@@ -2,7 +2,7 @@ // any_completion_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -75,18 +75,20 @@ #endif // !defined(GENERATING_DOCUMENTATION)    /// Default constructor.-  ASIO_DECL any_completion_executor() noexcept;+  ASIO_DECL any_completion_executor() ASIO_NOEXCEPT;    /// Construct in an empty state. Equivalent effects to default constructor.-  ASIO_DECL any_completion_executor(nullptr_t) noexcept;+  ASIO_DECL any_completion_executor(nullptr_t) ASIO_NOEXCEPT;    /// Copy constructor.   ASIO_DECL any_completion_executor(-      const any_completion_executor& e) noexcept;+      const any_completion_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.   ASIO_DECL any_completion_executor(-      any_completion_executor&& e) noexcept;+      any_completion_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Construct to point to the same target as another any_executor. #if defined(GENERATING_DOCUMENTATION)@@ -96,7 +98,7 @@ #else // defined(GENERATING_DOCUMENTATION)   template <typename OtherAnyExecutor>   any_completion_executor(OtherAnyExecutor e,-      constraint_t<+      typename constraint<         conditional<           !is_same<OtherAnyExecutor, any_completion_executor>::value             && is_base_of<execution::detail::any_executor_base,@@ -106,8 +108,8 @@               is_valid_target<OtherAnyExecutor>,           false_type         >::type::value-      > = 0)-    : base_type(static_cast<OtherAnyExecutor&&>(e))+      >::type = 0)+    : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e))   {   } #endif // defined(GENERATING_DOCUMENTATION)@@ -120,7 +122,7 @@ #else // defined(GENERATING_DOCUMENTATION)   template <typename OtherAnyExecutor>   any_completion_executor(std::nothrow_t, OtherAnyExecutor e,-      constraint_t<+      typename constraint<         conditional<           !is_same<OtherAnyExecutor, any_completion_executor>::value             && is_base_of<execution::detail::any_executor_base,@@ -130,19 +132,21 @@               is_valid_target<OtherAnyExecutor>,           false_type         >::type::value-      > = 0) noexcept-    : base_type(std::nothrow, static_cast<OtherAnyExecutor&&>(e))+      >::type = 0) ASIO_NOEXCEPT+    : base_type(std::nothrow, ASIO_MOVE_CAST(OtherAnyExecutor)(e))   {   } #endif // defined(GENERATING_DOCUMENTATION)    /// Construct to point to the same target as another any_executor.   ASIO_DECL any_completion_executor(std::nothrow_t,-      const any_completion_executor& e) noexcept;+      const any_completion_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Construct to point to the same target as another any_executor.   ASIO_DECL any_completion_executor(std::nothrow_t,-      any_completion_executor&& e) noexcept;+      any_completion_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Construct a polymorphic wrapper for the specified executor. #if defined(GENERATING_DOCUMENTATION)@@ -151,7 +155,7 @@ #else // defined(GENERATING_DOCUMENTATION)   template <ASIO_EXECUTION_EXECUTOR Executor>   any_completion_executor(Executor e,-      constraint_t<+      typename constraint<         conditional<           !is_same<Executor, any_completion_executor>::value             && !is_base_of<execution::detail::any_executor_base,@@ -160,8 +164,8 @@             Executor, supportable_properties_type>,           false_type         >::type::value-      > = 0)-    : base_type(static_cast<Executor&&>(e))+      >::type = 0)+    : base_type(ASIO_MOVE_CAST(Executor)(e))   {   } #endif // defined(GENERATING_DOCUMENTATION)@@ -173,7 +177,7 @@ #else // defined(GENERATING_DOCUMENTATION)   template <ASIO_EXECUTION_EXECUTOR Executor>   any_completion_executor(std::nothrow_t, Executor e,-      constraint_t<+      typename constraint<         conditional<           !is_same<Executor, any_completion_executor>::value             && !is_base_of<execution::detail::any_executor_base,@@ -182,19 +186,21 @@             Executor, supportable_properties_type>,           false_type         >::type::value-      > = 0) noexcept-    : base_type(std::nothrow, static_cast<Executor&&>(e))+      >::type = 0) ASIO_NOEXCEPT+    : base_type(std::nothrow, ASIO_MOVE_CAST(Executor)(e))   {   } #endif // defined(GENERATING_DOCUMENTATION)    /// Assignment operator.   ASIO_DECL any_completion_executor& operator=(-      const any_completion_executor& e) noexcept;+      const any_completion_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move assignment operator.   ASIO_DECL any_completion_executor& operator=(-      any_completion_executor&& e) noexcept;+      any_completion_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Assignment operator that sets the polymorphic wrapper to the empty state.   ASIO_DECL any_completion_executor& operator=(nullptr_t);@@ -203,7 +209,7 @@   ASIO_DECL ~any_completion_executor();    /// Swap targets with another polymorphic wrapper.-  ASIO_DECL void swap(any_completion_executor& other) noexcept;+  ASIO_DECL void swap(any_completion_executor& other) ASIO_NOEXCEPT;    /// Obtain a polymorphic wrapper with the specified property.   /**@@ -216,9 +222,9 @@    */   template <typename Property>   any_completion_executor require(const Property& p,-      constraint_t<+      typename constraint<         traits::require_member<const base_type&, const Property&>::is_valid-      > = 0) const+      >::type = 0) const   {     return static_cast<const base_type&>(*this).require(p);   }@@ -234,9 +240,9 @@    */   template <typename Property>   any_completion_executor prefer(const Property& p,-      constraint_t<+      typename constraint<         traits::prefer_member<const base_type&, const Property&>::is_valid-      > = 0) const+      >::type = 0) const   {     return static_cast<const base_type&>(*this).prefer(p);   }
link/modules/asio-standalone/asio/include/asio/any_completion_handler.hpp view
@@ -2,7 +2,7 @@ // any_completion_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -12,16 +12,20 @@ #define ASIO_ANY_COMPLETION_HANDLER_HPP  #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+    && defined(ASIO_HAS_MOVE) \+    && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+  || defined(GENERATING_DOCUMENTATION)+ #include <cstring> #include <functional> #include <memory> #include <utility> #include "asio/any_completion_executor.hpp"-#include "asio/any_io_executor.hpp" #include "asio/associated_allocator.hpp" #include "asio/associated_cancellation_slot.hpp" #include "asio/associated_executor.hpp"-#include "asio/associated_immediate_executor.hpp" #include "asio/cancellation_state.hpp" #include "asio/recycling_allocator.hpp" @@ -35,11 +39,11 @@ public:   template <typename S>   explicit any_completion_handler_impl_base(S&& slot)-    : cancel_state_(static_cast<S&&>(slot), enable_total_cancellation())+    : cancel_state_(ASIO_MOVE_CAST(S)(slot), enable_total_cancellation())   {   } -  cancellation_slot get_cancellation_slot() const noexcept+  cancellation_slot get_cancellation_slot() const ASIO_NOEXCEPT   {     return cancel_state_.slot();   }@@ -55,8 +59,8 @@ public:   template <typename S, typename H>   any_completion_handler_impl(S&& slot, H&& h)-    : any_completion_handler_impl_base(static_cast<S&&>(slot)),-      handler_(static_cast<H&&>(h))+    : any_completion_handler_impl_base(ASIO_MOVE_CAST(S)(slot)),+      handler_(ASIO_MOVE_CAST(H)(h))   {   } @@ -99,7 +103,7 @@      any_completion_handler_impl* ptr =       new (uninit_ptr.get()) any_completion_handler_impl(-        static_cast<S&&>(slot), static_cast<H&&>(h));+        ASIO_MOVE_CAST(S)(slot), ASIO_MOVE_CAST(H)(h));      uninit_ptr.release();     return ptr;@@ -115,20 +119,13 @@   }    any_completion_executor executor(-      const any_completion_executor& candidate) const noexcept+      const any_completion_executor& candidate) const ASIO_NOEXCEPT   {     return any_completion_executor(std::nothrow,         (get_associated_executor)(handler_, candidate));   } -  any_completion_executor immediate_executor(-      const any_io_executor& candidate) const noexcept-  {-    return any_completion_executor(std::nothrow,-        (get_associated_immediate_executor)(handler_, candidate));-  }--  void* allocate(std::size_t size, std::size_t align_size) const+  void* allocate(std::size_t size, std::size_t align) const   {     typename std::allocator_traits<       associated_allocator_t<Handler,@@ -137,13 +134,13 @@             (get_associated_allocator)(handler_,               asio::recycling_allocator<void>())); -    std::size_t space = size + align_size - 1;+    std::size_t space = size + align - 1;     unsigned char* base =       std::allocator_traits<decltype(alloc)>::allocate(         alloc, space + sizeof(std::ptrdiff_t));      void* p = base;-    if (detail::align(align_size, size, p, space))+    if (detail::align(align, size, p, space))     {       std::ptrdiff_t off = static_cast<unsigned char*>(p) - base;       std::memcpy(static_cast<unsigned char*>(p) + size, &off, sizeof(off));@@ -183,11 +180,11 @@           asio::recycling_allocator<void>())};      std::unique_ptr<any_completion_handler_impl, deleter> ptr(this, d);-    Handler handler(static_cast<Handler&&>(handler_));+    Handler handler(ASIO_MOVE_CAST(Handler)(handler_));     ptr.reset(); -    static_cast<Handler&&>(handler)(-        static_cast<Args&&>(args)...);+    ASIO_MOVE_CAST(Handler)(handler)(+        ASIO_MOVE_CAST(Args)(args)...);   }  private:@@ -210,14 +207,14 @@    void call(any_completion_handler_impl_base* impl, Args... args) const   {-    call_fn_(impl, static_cast<Args&&>(args)...);+    call_fn_(impl, ASIO_MOVE_CAST(Args)(args)...);   }    template <typename Handler>   static void impl(any_completion_handler_impl_base* impl, Args... args)   {     static_cast<any_completion_handler_impl<Handler>*>(impl)->call(-        static_cast<Args&&>(args)...);+        ASIO_MOVE_CAST(Args)(args)...);   }  private:@@ -308,36 +305,6 @@   type executor_fn_; }; -class any_completion_handler_immediate_executor_fn-{-public:-  using type = any_completion_executor(*)(-      any_completion_handler_impl_base*, const any_io_executor&);--  constexpr any_completion_handler_immediate_executor_fn(type fn)-    : immediate_executor_fn_(fn)-  {-  }--  any_completion_executor immediate_executor(-      any_completion_handler_impl_base* impl,-      const any_io_executor& candidate) const-  {-    return immediate_executor_fn_(impl, candidate);-  }--  template <typename Handler>-  static any_completion_executor impl(any_completion_handler_impl_base* impl,-      const any_io_executor& candidate)-  {-    return static_cast<any_completion_handler_impl<Handler>*>(-        impl)->immediate_executor(candidate);-  }--private:-  type immediate_executor_fn_;-};- class any_completion_handler_allocate_fn { public:@@ -400,7 +367,6 @@ class any_completion_handler_fn_table   : private any_completion_handler_destroy_fn,     private any_completion_handler_executor_fn,-    private any_completion_handler_immediate_executor_fn,     private any_completion_handler_allocate_fn,     private any_completion_handler_deallocate_fn,     private any_completion_handler_call_fns<Signatures...>@@ -410,13 +376,11 @@   constexpr any_completion_handler_fn_table(       any_completion_handler_destroy_fn::type destroy_fn,       any_completion_handler_executor_fn::type executor_fn,-      any_completion_handler_immediate_executor_fn::type immediate_executor_fn,       any_completion_handler_allocate_fn::type allocate_fn,       any_completion_handler_deallocate_fn::type deallocate_fn,       CallFns... call_fns)     : any_completion_handler_destroy_fn(destroy_fn),       any_completion_handler_executor_fn(executor_fn),-      any_completion_handler_immediate_executor_fn(immediate_executor_fn),       any_completion_handler_allocate_fn(allocate_fn),       any_completion_handler_deallocate_fn(deallocate_fn),       any_completion_handler_call_fns<Signatures...>(call_fns...)@@ -425,7 +389,6 @@    using any_completion_handler_destroy_fn::destroy;   using any_completion_handler_executor_fn::executor;-  using any_completion_handler_immediate_executor_fn::immediate_executor;   using any_completion_handler_allocate_fn::allocate;   using any_completion_handler_deallocate_fn::deallocate;   using any_completion_handler_call_fns<Signatures...>::call;@@ -438,7 +401,6 @@     value = any_completion_handler_fn_table<Signatures...>(         &any_completion_handler_destroy_fn::impl<Handler>,         &any_completion_handler_executor_fn::impl<Handler>,-        &any_completion_handler_immediate_executor_fn::impl<Handler>,         &any_completion_handler_allocate_fn::impl<Handler>,         &any_completion_handler_deallocate_fn::impl<Handler>,         &any_completion_handler_call_fn<Signatures>::template impl<Handler>...);@@ -469,7 +431,7 @@   detail::any_completion_handler_impl_base* impl_;    constexpr any_completion_handler_allocator(int,-      const any_completion_handler<Signatures...>& h) noexcept+      const any_completion_handler<Signatures...>& h) ASIO_NOEXCEPT     : fn_table_(h.fn_table_),       impl_(h.impl_)   {@@ -491,7 +453,7 @@   template <typename U>   constexpr any_completion_handler_allocator(       const any_completion_handler_allocator<U, Signatures...>& a)-    noexcept+    ASIO_NOEXCEPT     : fn_table_(a.fn_table_),       impl_(a.impl_)   {@@ -499,14 +461,14 @@    /// Equality operator.   constexpr bool operator==(-      const any_completion_handler_allocator& other) const noexcept+      const any_completion_handler_allocator& other) const ASIO_NOEXCEPT   {     return fn_table_ == other.fn_table_ && impl_ == other.impl_;   }    /// Inequality operator.   constexpr bool operator!=(-      const any_completion_handler_allocator& other) const noexcept+      const any_completion_handler_allocator& other) const ASIO_NOEXCEPT   {     return fn_table_ != other.fn_table_ || impl_ != other.impl_;   }@@ -514,15 +476,9 @@   /// Allocate space for @c n objects of the allocator's value type.   T* allocate(std::size_t n) const   {-    if (fn_table_)-    {-      return static_cast<T*>(-          fn_table_->allocate(-            impl_, sizeof(T) * n, alignof(T)));-    }-    std::bad_alloc ex;-    asio::detail::throw_exception(ex);-    return nullptr;+    return static_cast<T*>(+        fn_table_->allocate(+          impl_, sizeof(T) * n, alignof(T)));   }    /// Deallocate space for @c n objects of the allocator's value type.@@ -549,7 +505,7 @@   detail::any_completion_handler_impl_base* impl_;    constexpr any_completion_handler_allocator(int,-      const any_completion_handler<Signatures...>& h) noexcept+      const any_completion_handler<Signatures...>& h) ASIO_NOEXCEPT     : fn_table_(h.fn_table_),       impl_(h.impl_)   {@@ -571,7 +527,7 @@   template <typename U>   constexpr any_completion_handler_allocator(       const any_completion_handler_allocator<U, Signatures...>& a)-    noexcept+    ASIO_NOEXCEPT     : fn_table_(a.fn_table_),       impl_(a.impl_)   {@@ -579,14 +535,14 @@    /// Equality operator.   constexpr bool operator==(-      const any_completion_handler_allocator& other) const noexcept+      const any_completion_handler_allocator& other) const ASIO_NOEXCEPT   {     return fn_table_ == other.fn_table_ && impl_ == other.impl_;   }    /// Inequality operator.   constexpr bool operator!=(-      const any_completion_handler_allocator& other) const noexcept+      const any_completion_handler_allocator& other) const ASIO_NOEXCEPT   {     return fn_table_ != other.fn_table_ || impl_ != other.impl_;   }@@ -620,9 +576,6 @@   template <typename, typename>   friend struct associated_executor; -  template <typename, typename>-  friend struct associated_immediate_executor;-   const detail::any_completion_handler_fn_table<Signatures...>* fn_table_;   detail::any_completion_handler_impl_base* impl_; #endif // !defined(GENERATING_DOCUMENTATION)@@ -651,16 +604,16 @@   }    /// Construct an @c any_completion_handler to contain the specified target.-  template <typename H, typename Handler = decay_t<H>>+  template <typename H, typename Handler = typename decay<H>::type>   any_completion_handler(H&& h,-      constraint_t<-        !is_same<decay_t<H>, any_completion_handler>::value-      > = 0)+      typename constraint<+        !is_same<typename decay<H>::type, any_completion_handler>::value+      >::type = 0)     : fn_table_(         &detail::any_completion_handler_fn_table_instance<           Handler, Signatures...>::value),       impl_(detail::any_completion_handler_impl<Handler>::create(-            (get_associated_cancellation_slot)(h), static_cast<H&&>(h)))+            (get_associated_cancellation_slot)(h), ASIO_MOVE_CAST(H)(h)))   {   } @@ -668,7 +621,7 @@   /**    * After the operation, the moved-from object @c other has no target.    */-  any_completion_handler(any_completion_handler&& other) noexcept+  any_completion_handler(any_completion_handler&& other) ASIO_NOEXCEPT     : fn_table_(other.fn_table_),       impl_(other.impl_)   {@@ -681,15 +634,15 @@    * After the operation, the moved-from object @c other has no target.    */   any_completion_handler& operator=(-      any_completion_handler&& other) noexcept+      any_completion_handler&& other) ASIO_NOEXCEPT   {     any_completion_handler(-        static_cast<any_completion_handler&&>(other)).swap(*this);+        ASIO_MOVE_CAST(any_completion_handler)(other)).swap(*this);     return *this;   }    /// Assignment operator that sets the polymorphic wrapper to the empty state.-  any_completion_handler& operator=(nullptr_t) noexcept+  any_completion_handler& operator=(nullptr_t) ASIO_NOEXCEPT   {     any_completion_handler().swap(*this);     return *this;@@ -703,34 +656,34 @@   }    /// Test if the polymorphic wrapper is empty.-  constexpr explicit operator bool() const noexcept+  constexpr explicit operator bool() const ASIO_NOEXCEPT   {     return impl_ != nullptr;   }    /// Test if the polymorphic wrapper is non-empty.-  constexpr bool operator!() const noexcept+  constexpr bool operator!() const ASIO_NOEXCEPT   {     return impl_ == nullptr;   }    /// Swap the content of an @c any_completion_handler with another.-  void swap(any_completion_handler& other) noexcept+  void swap(any_completion_handler& other) ASIO_NOEXCEPT   {     std::swap(fn_table_, other.fn_table_);     std::swap(impl_, other.impl_);   }    /// Get the associated allocator.-  allocator_type get_allocator() const noexcept+  allocator_type get_allocator() const ASIO_NOEXCEPT   {     return allocator_type(0, *this);   }    /// Get the associated cancellation slot.-  cancellation_slot_type get_cancellation_slot() const noexcept+  cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT   {-    return impl_ ? impl_->get_cancellation_slot() : cancellation_slot_type();+    return impl_->get_cancellation_slot();   }    /// Function call operator.@@ -744,12 +697,12 @@    */   template <typename... Args>   auto operator()(Args&&... args)-    -> decltype(fn_table_->call(impl_, static_cast<Args&&>(args)...))+    -> decltype(fn_table_->call(impl_, ASIO_MOVE_CAST(Args)(args)...))   {     if (detail::any_completion_handler_impl_base* impl = impl_)     {       impl_ = nullptr;-      return fn_table_->call(impl, static_cast<Args&&>(args)...);+      return fn_table_->call(impl, ASIO_MOVE_CAST(Args)(args)...);     }     std::bad_function_call ex;     asio::detail::throw_exception(ex);@@ -757,28 +710,28 @@    /// Equality operator.   friend constexpr bool operator==(-      const any_completion_handler& a, nullptr_t) noexcept+      const any_completion_handler& a, nullptr_t) ASIO_NOEXCEPT   {     return a.impl_ == nullptr;   }    /// Equality operator.   friend constexpr bool operator==(-      nullptr_t, const any_completion_handler& b) noexcept+      nullptr_t, const any_completion_handler& b) ASIO_NOEXCEPT   {     return nullptr == b.impl_;   }    /// Inequality operator.   friend constexpr bool operator!=(-      const any_completion_handler& a, nullptr_t) noexcept+      const any_completion_handler& a, nullptr_t) ASIO_NOEXCEPT   {     return a.impl_ != nullptr;   }    /// Inequality operator.   friend constexpr bool operator!=(-      nullptr_t, const any_completion_handler& b) noexcept+      nullptr_t, const any_completion_handler& b) ASIO_NOEXCEPT   {     return nullptr != b.impl_;   }@@ -790,33 +743,20 @@   using type = any_completion_executor;    static type get(const any_completion_handler<Signatures...>& handler,-      const Candidate& candidate = Candidate()) noexcept-  {-    any_completion_executor any_candidate(std::nothrow, candidate);-    return handler.fn_table_-      ? handler.fn_table_->executor(handler.impl_, any_candidate)-      : any_candidate;-  }-};--template <typename... Signatures, typename Candidate>-struct associated_immediate_executor<-    any_completion_handler<Signatures...>, Candidate>-{-  using type = any_completion_executor;--  static type get(const any_completion_handler<Signatures...>& handler,-      const Candidate& candidate = Candidate()) noexcept+      const Candidate& candidate = Candidate()) ASIO_NOEXCEPT   {-    any_io_executor any_candidate(std::nothrow, candidate);-    return handler.fn_table_-      ? handler.fn_table_->immediate_executor(handler.impl_, any_candidate)-      : any_candidate;+    return handler.fn_table_->executor(handler.impl_,+        any_completion_executor(std::nothrow, candidate));   } };  } // namespace asio  #include "asio/detail/pop_options.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+       //     && defined(ASIO_HAS_MOVE)+       //     && defined(ASIO_HAS_VARIADIC_TEMPLATES))+       //   || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_ANY_COMPLETION_HANDLER_HPP
link/modules/asio-standalone/asio/include/asio/any_io_executor.hpp view
@@ -2,7 +2,7 @@ // any_io_executor.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -87,16 +87,18 @@ #endif // !defined(GENERATING_DOCUMENTATION)    /// Default constructor.-  ASIO_DECL any_io_executor() noexcept;+  ASIO_DECL any_io_executor() ASIO_NOEXCEPT;    /// Construct in an empty state. Equivalent effects to default constructor.-  ASIO_DECL any_io_executor(nullptr_t) noexcept;+  ASIO_DECL any_io_executor(nullptr_t) ASIO_NOEXCEPT;    /// Copy constructor.-  ASIO_DECL any_io_executor(const any_io_executor& e) noexcept;+  ASIO_DECL any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.-  ASIO_DECL any_io_executor(any_io_executor&& e) noexcept;+  ASIO_DECL any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Construct to point to the same target as another any_executor. #if defined(GENERATING_DOCUMENTATION)@@ -105,8 +107,8 @@ #else // defined(GENERATING_DOCUMENTATION)   template <typename OtherAnyExecutor>   any_io_executor(OtherAnyExecutor e,-      constraint_t<-        conditional_t<+      typename constraint<+        conditional<           !is_same<OtherAnyExecutor, any_io_executor>::value             && is_base_of<execution::detail::any_executor_base,               OtherAnyExecutor>::value,@@ -114,9 +116,9 @@             0, supportable_properties_type>::template               is_valid_target<OtherAnyExecutor>,           false_type-        >::value-      > = 0)-    : base_type(static_cast<OtherAnyExecutor&&>(e))+        >::type::value+      >::type = 0)+    : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e))   {   } #endif // defined(GENERATING_DOCUMENTATION)@@ -129,8 +131,8 @@ #else // defined(GENERATING_DOCUMENTATION)   template <typename OtherAnyExecutor>   any_io_executor(std::nothrow_t, OtherAnyExecutor e,-      constraint_t<-        conditional_t<+      typename constraint<+        conditional<           !is_same<OtherAnyExecutor, any_io_executor>::value             && is_base_of<execution::detail::any_executor_base,               OtherAnyExecutor>::value,@@ -138,19 +140,22 @@             0, supportable_properties_type>::template               is_valid_target<OtherAnyExecutor>,           false_type-        >::value-      > = 0) noexcept-    : base_type(std::nothrow, static_cast<OtherAnyExecutor&&>(e))+        >::type::value+      >::type = 0) ASIO_NOEXCEPT+    : base_type(std::nothrow, ASIO_MOVE_CAST(OtherAnyExecutor)(e))   {   } #endif // defined(GENERATING_DOCUMENTATION)    /// Construct to point to the same target as another any_executor.   ASIO_DECL any_io_executor(std::nothrow_t,-      const any_io_executor& e) noexcept;+      const any_io_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Construct to point to the same target as another any_executor.-  ASIO_DECL any_io_executor(std::nothrow_t, any_io_executor&& e) noexcept;+  ASIO_DECL any_io_executor(std::nothrow_t,+      any_io_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Construct a polymorphic wrapper for the specified executor. #if defined(GENERATING_DOCUMENTATION)@@ -159,17 +164,17 @@ #else // defined(GENERATING_DOCUMENTATION)   template <ASIO_EXECUTION_EXECUTOR Executor>   any_io_executor(Executor e,-      constraint_t<-        conditional_t<+      typename constraint<+        conditional<           !is_same<Executor, any_io_executor>::value             && !is_base_of<execution::detail::any_executor_base,               Executor>::value,           execution::detail::is_valid_target_executor<             Executor, supportable_properties_type>,           false_type-        >::value-      > = 0)-    : base_type(static_cast<Executor&&>(e))+        >::type::value+      >::type = 0)+    : base_type(ASIO_MOVE_CAST(Executor)(e))   {   } #endif // defined(GENERATING_DOCUMENTATION)@@ -181,27 +186,30 @@ #else // defined(GENERATING_DOCUMENTATION)   template <ASIO_EXECUTION_EXECUTOR Executor>   any_io_executor(std::nothrow_t, Executor e,-      constraint_t<-        conditional_t<+      typename constraint<+        conditional<           !is_same<Executor, any_io_executor>::value             && !is_base_of<execution::detail::any_executor_base,               Executor>::value,           execution::detail::is_valid_target_executor<             Executor, supportable_properties_type>,           false_type-        >::value-      > = 0) noexcept-    : base_type(std::nothrow, static_cast<Executor&&>(e))+        >::type::value+      >::type = 0) ASIO_NOEXCEPT+    : base_type(std::nothrow, ASIO_MOVE_CAST(Executor)(e))   {   } #endif // defined(GENERATING_DOCUMENTATION)    /// Assignment operator.   ASIO_DECL any_io_executor& operator=(-      const any_io_executor& e) noexcept;+      const any_io_executor& e) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move assignment operator.-  ASIO_DECL any_io_executor& operator=(any_io_executor&& e) noexcept;+  ASIO_DECL any_io_executor& operator=(+      any_io_executor&& e) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Assignment operator that sets the polymorphic wrapper to the empty state.   ASIO_DECL any_io_executor& operator=(nullptr_t);@@ -210,7 +218,7 @@   ASIO_DECL ~any_io_executor();    /// Swap targets with another polymorphic wrapper.-  ASIO_DECL void swap(any_io_executor& other) noexcept;+  ASIO_DECL void swap(any_io_executor& other) ASIO_NOEXCEPT;    /// Obtain a polymorphic wrapper with the specified property.   /**@@ -223,9 +231,9 @@    */   template <typename Property>   any_io_executor require(const Property& p,-      constraint_t<+      typename constraint<         traits::require_member<const base_type&, const Property&>::is_valid-      > = 0) const+      >::type = 0) const   {     return static_cast<const base_type&>(*this).require(p);   }@@ -241,9 +249,9 @@    */   template <typename Property>   any_io_executor prefer(const Property& p,-      constraint_t<+      typename constraint<         traits::prefer_member<const base_type&, const Property&>::is_valid-      > = 0) const+      >::type = 0) const   {     return static_cast<const base_type&>(*this).prefer(p);   }
link/modules/asio-standalone/asio/include/asio/append.hpp view
@@ -2,7 +2,7 @@ // append.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+    && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+  || defined(GENERATING_DOCUMENTATION)+ #include <tuple> #include "asio/detail/type_traits.hpp" @@ -32,9 +37,11 @@ public:   /// Constructor.   template <typename T, typename... V>-  constexpr explicit append_t(T&& completion_token, V&&... values)-    : token_(static_cast<T&&>(completion_token)),-      values_(static_cast<V&&>(values)...)+  ASIO_CONSTEXPR explicit append_t(+      ASIO_MOVE_ARG(T) completion_token,+      ASIO_MOVE_ARG(V)... values)+    : token_(ASIO_MOVE_CAST(T)(completion_token)),+      values_(ASIO_MOVE_CAST(V)(values)...)   {   } @@ -47,13 +54,15 @@ /// arguments should be passed additional values after the results of the /// operation. template <typename CompletionToken, typename... Values>-ASIO_NODISCARD inline constexpr-append_t<decay_t<CompletionToken>, decay_t<Values>...>-append(CompletionToken&& completion_token, Values&&... values)+ASIO_NODISCARD inline ASIO_CONSTEXPR append_t<+  typename decay<CompletionToken>::type, typename decay<Values>::type...>+append(ASIO_MOVE_ARG(CompletionToken) completion_token,+    ASIO_MOVE_ARG(Values)... values) {-  return append_t<decay_t<CompletionToken>, decay_t<Values>...>(-      static_cast<CompletionToken&&>(completion_token),-      static_cast<Values&&>(values)...);+  return append_t<+    typename decay<CompletionToken>::type, typename decay<Values>::type...>(+      ASIO_MOVE_CAST(CompletionToken)(completion_token),+      ASIO_MOVE_CAST(Values)(values)...); }  } // namespace asio@@ -61,5 +70,9 @@ #include "asio/detail/pop_options.hpp"  #include "asio/impl/append.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+       //     && defined(ASIO_HAS_VARIADIC_TEMPLATES))+       //   || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_APPEND_HPP
link/modules/asio-standalone/asio/include/asio/as_tuple.hpp view
@@ -2,7 +2,7 @@ // as_tuple.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+    && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+  || defined(GENERATING_DOCUMENTATION)+ #include "asio/detail/type_traits.hpp"  #include "asio/detail/push_options.hpp"@@ -45,18 +50,18 @@    * token is itself defaulted as an argument to allow it to capture a source    * location.    */-  constexpr as_tuple_t(+  ASIO_CONSTEXPR as_tuple_t(       default_constructor_tag = default_constructor_tag(),       CompletionToken token = CompletionToken())-    : token_(static_cast<CompletionToken&&>(token))+    : token_(ASIO_MOVE_CAST(CompletionToken)(token))   {   }    /// Constructor.   template <typename T>-  constexpr explicit as_tuple_t(-      T&& completion_token)-    : token_(static_cast<T&&>(completion_token))+  ASIO_CONSTEXPR explicit as_tuple_t(+      ASIO_MOVE_ARG(T) completion_token)+    : token_(ASIO_MOVE_CAST(T)(completion_token))   {   } @@ -71,13 +76,13 @@     /// Construct the adapted executor from the inner executor type.     template <typename InnerExecutor1>     executor_with_default(const InnerExecutor1& ex,-        constraint_t<-          conditional_t<+        typename constraint<+          conditional<             !is_same<InnerExecutor1, executor_with_default>::value,             is_convertible<InnerExecutor1, InnerExecutor>,             false_type-          >::value-        > = 0) noexcept+          >::type::value+        >::type = 0) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -85,68 +90,50 @@    /// Type alias to adapt an I/O object to use @c as_tuple_t as its   /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)   template <typename T>   using as_default_on_t = typename T::template rebind_executor<-      executor_with_default<typename T::executor_type>>::other;+      executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)    /// Function helper to adapt an I/O object to use @c as_tuple_t as its   /// default completion token type.   template <typename T>-  static typename decay_t<T>::template rebind_executor<-      executor_with_default<typename decay_t<T>::executor_type>+  static typename decay<T>::type::template rebind_executor<+      executor_with_default<typename decay<T>::type::executor_type>     >::other-  as_default_on(T&& object)+  as_default_on(ASIO_MOVE_ARG(T) object)   {-    return typename decay_t<T>::template rebind_executor<-        executor_with_default<typename decay_t<T>::executor_type>-      >::other(static_cast<T&&>(object));+    return typename decay<T>::type::template rebind_executor<+        executor_with_default<typename decay<T>::type::executor_type>+      >::other(ASIO_MOVE_CAST(T)(object));   }  //private:   CompletionToken token_; }; -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler arguments should be combined into a single tuple-/// argument.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-struct partial_as_tuple+/// Adapt a @ref completion_token to specify that the completion handler+/// arguments should be combined into a single tuple argument.+template <typename CompletionToken>+ASIO_NODISCARD inline+ASIO_CONSTEXPR as_tuple_t<typename decay<CompletionToken>::type>+as_tuple(ASIO_MOVE_ARG(CompletionToken) completion_token) {-  /// Default constructor.-  constexpr partial_as_tuple()-  {-  }--  /// Adapt a @ref completion_token to specify that the completion handler-  /// arguments should be combined into a single tuple argument.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  constexpr as_tuple_t<decay_t<CompletionToken>>-  operator()(CompletionToken&& completion_token) const-  {-    return as_tuple_t<decay_t<CompletionToken>>(-        static_cast<CompletionToken&&>(completion_token));-  }-};--/// A function object that adapts a @ref completion_token to specify that the-/// completion handler arguments should be combined into a single tuple-/// argument.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-ASIO_INLINE_VARIABLE constexpr partial_as_tuple as_tuple;+  return as_tuple_t<typename decay<CompletionToken>::type>(+      ASIO_MOVE_CAST(CompletionToken)(completion_token));+}  } // namespace asio  #include "asio/detail/pop_options.hpp"  #include "asio/impl/as_tuple.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+       //     && defined(ASIO_HAS_VARIADIC_TEMPLATES))+       //   || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_AS_TUPLE_HPP
link/modules/asio-standalone/asio/include/asio/associated_allocator.hpp view
@@ -2,7 +2,7 @@ // associated_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -36,7 +36,9 @@ };  template <typename T>-struct has_allocator_type<T, void_t<typename T::allocator_type>> : true_type+struct has_allocator_type<T,+  typename void_type<typename T::allocator_type>::type>+    : true_type { }; @@ -47,30 +49,33 @@    typedef A type; -  static type get(const T&) noexcept+  static type get(const T&) ASIO_NOEXCEPT   {     return type();   } -  static const type& get(const T&, const A& a) noexcept+  static const type& get(const T&, const A& a) ASIO_NOEXCEPT   {     return a;   } };  template <typename T, typename A>-struct associated_allocator_impl<T, A, void_t<typename T::allocator_type>>+struct associated_allocator_impl<T, A,+  typename void_type<typename T::allocator_type>::type> {   typedef typename T::allocator_type type; -  static auto get(const T& t) noexcept-    -> decltype(t.get_allocator())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const T& t) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_allocator()))   {     return t.get_allocator();   } -  static auto get(const T& t, const A&) noexcept-    -> decltype(t.get_allocator())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const T& t, const A&) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_allocator()))   {     return t.get_allocator();   }@@ -78,12 +83,12 @@  template <typename T, typename A> struct associated_allocator_impl<T, A,-  enable_if_t<+  typename enable_if<     !has_allocator_type<T>::value-  >,-  void_t<+  >::type,+  typename void_type<     typename associator<associated_allocator, T, A>::type-  >> : associator<associated_allocator, T, A>+  >::type> : associator<associated_allocator, T, A> { }; @@ -110,7 +115,7 @@  * get(t,a) and with return type @c type or a (possibly const) reference to @c  * type.  */-template <typename T, typename Allocator = std::allocator<void>>+template <typename T, typename Allocator = std::allocator<void> > struct associated_allocator #if !defined(GENERATING_DOCUMENTATION)   : detail::associated_allocator_impl<T, Allocator>@@ -123,11 +128,11 @@    /// If @c T has a nested type @c allocator_type, returns   /// <tt>t.get_allocator()</tt>. Otherwise returns @c type().-  static decltype(auto) get(const T& t) noexcept;+  static decltype(auto) get(const T& t) ASIO_NOEXCEPT;    /// If @c T has a nested type @c allocator_type, returns   /// <tt>t.get_allocator()</tt>. Otherwise returns @c a.-  static decltype(auto) get(const T& t, const Allocator& a) noexcept;+  static decltype(auto) get(const T& t, const Allocator& a) ASIO_NOEXCEPT; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -137,7 +142,7 @@  */ template <typename T> ASIO_NODISCARD inline typename associated_allocator<T>::type-get_associated_allocator(const T& t) noexcept+get_associated_allocator(const T& t) ASIO_NOEXCEPT {   return associated_allocator<T>::get(t); }@@ -147,17 +152,23 @@  * @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>  */ template <typename T, typename Allocator>-ASIO_NODISCARD inline auto get_associated_allocator(-    const T& t, const Allocator& a) noexcept-  -> decltype(associated_allocator<T, Allocator>::get(t, a))+ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2(+    typename associated_allocator<T, Allocator>::type)+get_associated_allocator(const T& t, const Allocator& a) ASIO_NOEXCEPT+  ASIO_AUTO_RETURN_TYPE_SUFFIX((+    associated_allocator<T, Allocator>::get(t, a))) {   return associated_allocator<T, Allocator>::get(t, a); } -template <typename T, typename Allocator = std::allocator<void>>+#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename T, typename Allocator = std::allocator<void> > using associated_allocator_t   = typename associated_allocator<T, Allocator>::type; +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ namespace detail {  template <typename T, typename A, typename = void>@@ -167,19 +178,22 @@  template <typename T, typename A> struct associated_allocator_forwarding_base<T, A,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_allocator<T,           A>::asio_associated_allocator_is_unspecialised,         void       >::value-    >>+    >::type> {   typedef void asio_associated_allocator_is_unspecialised; };  } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \+  || defined(GENERATING_DOCUMENTATION)+ /// Specialisation of associated_allocator for @c std::reference_wrapper. template <typename T, typename Allocator> struct associated_allocator<reference_wrapper<T>, Allocator>@@ -193,19 +207,24 @@    /// Forwards the request to get the allocator to the associator specialisation   /// for the unwrapped type @c T.-  static type get(reference_wrapper<T> t) noexcept+  static type get(reference_wrapper<T> t) ASIO_NOEXCEPT   {     return associated_allocator<T, Allocator>::get(t.get());   }    /// Forwards the request to get the allocator to the associator specialisation   /// for the unwrapped type @c T.-  static auto get(reference_wrapper<T> t, const Allocator& a) noexcept-    -> decltype(associated_allocator<T, Allocator>::get(t.get(), a))+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      reference_wrapper<T> t, const Allocator& a) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      associated_allocator<T, Allocator>::get(t.get(), a)))   {     return associated_allocator<T, Allocator>::get(t.get(), a);   } };++#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+       //   || defined(GENERATING_DOCUMENTATION)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/associated_cancellation_slot.hpp view
@@ -2,7 +2,7 @@ // associated_cancellation_slot.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -36,8 +36,9 @@ };  template <typename T>-struct has_cancellation_slot_type<T, void_t<typename T::cancellation_slot_type>>-  : true_type+struct has_cancellation_slot_type<T,+  typename void_type<typename T::cancellation_slot_type>::type>+    : true_type { }; @@ -48,12 +49,12 @@    typedef S type; -  static type get(const T&) noexcept+  static type get(const T&) ASIO_NOEXCEPT   {     return type();   } -  static const type& get(const T&, const S& s) noexcept+  static const type& get(const T&, const S& s) ASIO_NOEXCEPT   {     return s;   }@@ -61,18 +62,20 @@  template <typename T, typename S> struct associated_cancellation_slot_impl<T, S,-  void_t<typename T::cancellation_slot_type>>+  typename void_type<typename T::cancellation_slot_type>::type> {   typedef typename T::cancellation_slot_type type; -  static auto get(const T& t) noexcept-    -> decltype(t.get_cancellation_slot())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const T& t) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_cancellation_slot()))   {     return t.get_cancellation_slot();   } -  static auto get(const T& t, const S&) noexcept-    -> decltype(t.get_cancellation_slot())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const T& t, const S&) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_cancellation_slot()))   {     return t.get_cancellation_slot();   }@@ -80,12 +83,12 @@  template <typename T, typename S> struct associated_cancellation_slot_impl<T, S,-  enable_if_t<+  typename enable_if<     !has_cancellation_slot_type<T>::value-  >,-  void_t<+  >::type,+  typename void_type<     typename associator<associated_cancellation_slot, T, S>::type-  >> : associator<associated_cancellation_slot, T, S>+  >::type> : associator<associated_cancellation_slot, T, S> { }; @@ -126,12 +129,12 @@    /// If @c T has a nested type @c cancellation_slot_type, returns   /// <tt>t.get_cancellation_slot()</tt>. Otherwise returns @c type().-  static decltype(auto) get(const T& t) noexcept;+  static decltype(auto) get(const T& t) ASIO_NOEXCEPT;    /// If @c T has a nested type @c cancellation_slot_type, returns   /// <tt>t.get_cancellation_slot()</tt>. Otherwise returns @c s.   static decltype(auto) get(const T& t,-      const CancellationSlot& s) noexcept;+      const CancellationSlot& s) ASIO_NOEXCEPT; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -141,7 +144,7 @@  */ template <typename T> ASIO_NODISCARD inline typename associated_cancellation_slot<T>::type-get_associated_cancellation_slot(const T& t) noexcept+get_associated_cancellation_slot(const T& t) ASIO_NOEXCEPT {   return associated_cancellation_slot<T>::get(t); }@@ -152,17 +155,24 @@  * CancellationSlot>::get(t, st)</tt>  */ template <typename T, typename CancellationSlot>-ASIO_NODISCARD inline auto get_associated_cancellation_slot(-    const T& t, const CancellationSlot& st) noexcept-  -> decltype(associated_cancellation_slot<T, CancellationSlot>::get(t, st))+ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2(+    typename associated_cancellation_slot<T, CancellationSlot>::type)+get_associated_cancellation_slot(const T& t,+    const CancellationSlot& st) ASIO_NOEXCEPT+  ASIO_AUTO_RETURN_TYPE_SUFFIX((+    associated_cancellation_slot<T, CancellationSlot>::get(t, st))) {   return associated_cancellation_slot<T, CancellationSlot>::get(t, st); } +#if defined(ASIO_HAS_ALIAS_TEMPLATES)+ template <typename T, typename CancellationSlot = cancellation_slot> using associated_cancellation_slot_t =   typename associated_cancellation_slot<T, CancellationSlot>::type; +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ namespace detail {  template <typename T, typename S, typename = void>@@ -172,19 +182,22 @@  template <typename T, typename S> struct associated_cancellation_slot_forwarding_base<T, S,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_cancellation_slot<T,           S>::asio_associated_cancellation_slot_is_unspecialised,         void       >::value-    >>+    >::type> {   typedef void asio_associated_cancellation_slot_is_unspecialised; };  } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \+  || defined(GENERATING_DOCUMENTATION)+ /// Specialisation of associated_cancellation_slot for @c /// std::reference_wrapper. template <typename T, typename CancellationSlot>@@ -199,20 +212,24 @@    /// Forwards the request to get the cancellation slot to the associator   /// specialisation for the unwrapped type @c T.-  static type get(reference_wrapper<T> t) noexcept+  static type get(reference_wrapper<T> t) ASIO_NOEXCEPT   {     return associated_cancellation_slot<T, CancellationSlot>::get(t.get());   }    /// Forwards the request to get the cancellation slot to the associator   /// specialisation for the unwrapped type @c T.-  static auto get(reference_wrapper<T> t, const CancellationSlot& s) noexcept-    -> decltype(-      associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s))+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(reference_wrapper<T> t,+      const CancellationSlot& s) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s)))   {     return associated_cancellation_slot<T, CancellationSlot>::get(t.get(), s);   } };++#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+       //   || defined(GENERATING_DOCUMENTATION)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/associated_executor.hpp view
@@ -2,7 +2,7 @@ // associated_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -38,7 +38,8 @@ };  template <typename T>-struct has_executor_type<T, void_t<typename T::executor_type>>+struct has_executor_type<T,+  typename void_type<typename T::executor_type>::type>     : true_type { };@@ -50,30 +51,33 @@    typedef E type; -  static type get(const T&) noexcept+  static type get(const T&) ASIO_NOEXCEPT   {     return type();   } -  static const type& get(const T&, const E& e) noexcept+  static const type& get(const T&, const E& e) ASIO_NOEXCEPT   {     return e;   } };  template <typename T, typename E>-struct associated_executor_impl<T, E, void_t<typename T::executor_type>>+struct associated_executor_impl<T, E,+  typename void_type<typename T::executor_type>::type> {   typedef typename T::executor_type type; -  static auto get(const T& t) noexcept-    -> decltype(t.get_executor())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const T& t) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor()))   {     return t.get_executor();   } -  static auto get(const T& t, const E&) noexcept-    -> decltype(t.get_executor())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const T& t, const E&) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor()))   {     return t.get_executor();   }@@ -81,12 +85,12 @@  template <typename T, typename E> struct associated_executor_impl<T, E,-  enable_if_t<+  typename enable_if<     !has_executor_type<T>::value-  >,-  void_t<+  >::type,+  typename void_type<     typename associator<associated_executor, T, E>::type-  >> : associator<associated_executor, T, E>+  >::type> : associator<associated_executor, T, E> { }; @@ -126,11 +130,11 @@    /// If @c T has a nested type @c executor_type, returns   /// <tt>t.get_executor()</tt>. Otherwise returns @c type().-  static decltype(auto) get(const T& t) noexcept;+  static decltype(auto) get(const T& t) ASIO_NOEXCEPT;    /// If @c T has a nested type @c executor_type, returns   /// <tt>t.get_executor()</tt>. Otherwise returns @c ex.-  static decltype(auto) get(const T& t, const Executor& ex) noexcept;+  static decltype(auto) get(const T& t, const Executor& ex) ASIO_NOEXCEPT; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -140,7 +144,7 @@  */ template <typename T> ASIO_NODISCARD inline typename associated_executor<T>::type-get_associated_executor(const T& t) noexcept+get_associated_executor(const T& t) ASIO_NOEXCEPT {   return associated_executor<T>::get(t); }@@ -150,12 +154,14 @@  * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>  */ template <typename T, typename Executor>-ASIO_NODISCARD inline auto get_associated_executor(-    const T& t, const Executor& ex,-    constraint_t<+ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2(+    typename associated_executor<T, Executor>::type)+get_associated_executor(const T& t, const Executor& ex,+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0) noexcept-  -> decltype(associated_executor<T, Executor>::get(t, ex))+    >::type = 0) ASIO_NOEXCEPT+  ASIO_AUTO_RETURN_TYPE_SUFFIX((+    associated_executor<T, Executor>::get(t, ex))) {   return associated_executor<T, Executor>::get(t, ex); }@@ -169,16 +175,20 @@ ASIO_NODISCARD inline typename associated_executor<T,     typename ExecutionContext::executor_type>::type get_associated_executor(const T& t, ExecutionContext& ctx,-    constraint_t<is_convertible<ExecutionContext&,-      execution_context&>::value> = 0) noexcept+    typename constraint<is_convertible<ExecutionContext&,+      execution_context&>::value>::type = 0) ASIO_NOEXCEPT {   return associated_executor<T,     typename ExecutionContext::executor_type>::get(t, ctx.get_executor()); } +#if defined(ASIO_HAS_ALIAS_TEMPLATES)+ template <typename T, typename Executor = system_executor> using associated_executor_t = typename associated_executor<T, Executor>::type; +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ namespace detail {  template <typename T, typename E, typename = void>@@ -188,19 +198,22 @@  template <typename T, typename E> struct associated_executor_forwarding_base<T, E,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_executor<T,           E>::asio_associated_executor_is_unspecialised,         void       >::value-    >>+    >::type> {   typedef void asio_associated_executor_is_unspecialised; };  } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \+  || defined(GENERATING_DOCUMENTATION)+ /// Specialisation of associated_executor for @c std::reference_wrapper. template <typename T, typename Executor> struct associated_executor<reference_wrapper<T>, Executor>@@ -214,19 +227,24 @@    /// Forwards the request to get the executor to the associator specialisation   /// for the unwrapped type @c T.-  static type get(reference_wrapper<T> t) noexcept+  static type get(reference_wrapper<T> t) ASIO_NOEXCEPT   {     return associated_executor<T, Executor>::get(t.get());   }    /// Forwards the request to get the executor to the associator specialisation   /// for the unwrapped type @c T.-  static auto get(reference_wrapper<T> t, const Executor& ex) noexcept-    -> decltype(associated_executor<T, Executor>::get(t.get(), ex))+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      reference_wrapper<T> t, const Executor& ex) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      associated_executor<T, Executor>::get(t.get(), ex)))   {     return associated_executor<T, Executor>::get(t.get(), ex);   } };++#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+       //   || defined(GENERATING_DOCUMENTATION)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/associated_immediate_executor.hpp view
@@ -2,7 +2,7 @@ // associated_immediate_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -41,7 +41,7 @@  template <typename T> struct has_immediate_executor_type<T,-  void_t<typename T::immediate_executor_type>>+  typename void_type<typename T::immediate_executor_type>::type>     : true_type { };@@ -49,10 +49,9 @@ template <typename E, typename = void, typename = void> struct default_immediate_executor {-  typedef decay_t<require_result_t<E, execution::blocking_t::never_t>> type;+  typedef typename require_result<E, execution::blocking_t::never_t>::type type; -  static auto get(const E& e) noexcept-    -> decltype(asio::require(e, execution::blocking.never))+  static type get(const E& e) ASIO_NOEXCEPT   {     return asio::require(e, execution::blocking.never);   }@@ -60,57 +59,59 @@  template <typename E> struct default_immediate_executor<E,-  enable_if_t<+  typename enable_if<     !execution::is_executor<E>::value-  >,-  enable_if_t<+  >::type,+  typename enable_if<     is_executor<E>::value-  >>+  >::type> {   class type : public E   {   public:     template <typename Executor1>     explicit type(const Executor1& e,-        constraint_t<-          conditional_t<+        typename constraint<+          conditional<             !is_same<Executor1, type>::value,             is_convertible<Executor1, E>,             false_type-          >::value-        > = 0) noexcept+          >::type::value+        >::type = 0) ASIO_NOEXCEPT       : E(e)     {     } -    type(const type& other) noexcept+    type(const type& other) ASIO_NOEXCEPT       : E(static_cast<const E&>(other))     {     } -    type(type&& other) noexcept-      : E(static_cast<E&&>(other))+#if defined(ASIO_HAS_MOVE)+    type(type&& other) ASIO_NOEXCEPT+      : E(ASIO_MOVE_CAST(E)(other))     {     }+#endif // defined(ASIO_HAS_MOVE)      template <typename Function, typename Allocator>-    void dispatch(Function&& f, const Allocator& a) const+    void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const     {-      this->post(static_cast<Function&&>(f), a);+      this->post(ASIO_MOVE_CAST(Function)(f), a);     } -    friend bool operator==(const type& a, const type& b) noexcept+    friend bool operator==(const type& a, const type& b) ASIO_NOEXCEPT     {       return static_cast<const E&>(a) == static_cast<const E&>(b);     } -    friend bool operator!=(const type& a, const type& b) noexcept+    friend bool operator!=(const type& a, const type& b) ASIO_NOEXCEPT     {       return static_cast<const E&>(a) != static_cast<const E&>(b);     }   }; -  static type get(const E& e) noexcept+  static type get(const E& e) ASIO_NOEXCEPT   {     return type(e);   }@@ -123,8 +124,9 @@    typedef typename default_immediate_executor<E>::type type; -  static auto get(const T&, const E& e) noexcept-    -> decltype(default_immediate_executor<E>::get(e))+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const T&, const E& e) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((default_immediate_executor<E>::get(e)))   {     return default_immediate_executor<E>::get(e);   }@@ -132,12 +134,13 @@  template <typename T, typename E> struct associated_immediate_executor_impl<T, E,-  void_t<typename T::immediate_executor_type>>+  typename void_type<typename T::immediate_executor_type>::type> {   typedef typename T::immediate_executor_type type; -  static auto get(const T& t, const E&) noexcept-    -> decltype(t.get_immediate_executor())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const T& t, const E&) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_immediate_executor()))   {     return t.get_immediate_executor();   }@@ -145,12 +148,12 @@  template <typename T, typename E> struct associated_immediate_executor_impl<T, E,-  enable_if_t<+  typename enable_if<     !has_immediate_executor_type<T>::value-  >,-  void_t<+  >::type,+  typename void_type<     typename associator<associated_immediate_executor, T, E>::type-  >> : associator<associated_immediate_executor, T, E>+  >::type> : associator<associated_immediate_executor, T, E> { }; @@ -191,7 +194,7 @@   /// If @c T has a nested type @c immediate_executor_type, returns   /// <tt>t.get_immediate_executor()</tt>. Otherwise returns   /// <tt>asio::require(ex, asio::execution::blocking.never)</tt>.-  static decltype(auto) get(const T& t, const Executor& ex) noexcept;+  static decltype(auto) get(const T& t, const Executor& ex) ASIO_NOEXCEPT; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -200,12 +203,14 @@  * @returns <tt>associated_immediate_executor<T, Executor>::get(t, ex)</tt>  */ template <typename T, typename Executor>-ASIO_NODISCARD inline auto get_associated_immediate_executor(-    const T& t, const Executor& ex,-    constraint_t<+ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2(+    typename associated_immediate_executor<T, Executor>::type)+get_associated_immediate_executor(const T& t, const Executor& ex,+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0) noexcept-  -> decltype(associated_immediate_executor<T, Executor>::get(t, ex))+    >::type = 0) ASIO_NOEXCEPT+  ASIO_AUTO_RETURN_TYPE_SUFFIX((+    associated_immediate_executor<T, Executor>::get(t, ex))) {   return associated_immediate_executor<T, Executor>::get(t, ex); }@@ -219,18 +224,21 @@ ASIO_NODISCARD inline typename associated_immediate_executor<T,     typename ExecutionContext::executor_type>::type get_associated_immediate_executor(const T& t, ExecutionContext& ctx,-    constraint_t<-      is_convertible<ExecutionContext&, execution_context&>::value-    > = 0) noexcept+    typename constraint<is_convertible<ExecutionContext&,+      execution_context&>::value>::type = 0) ASIO_NOEXCEPT {   return associated_immediate_executor<T,     typename ExecutionContext::executor_type>::get(t, ctx.get_executor()); } +#if defined(ASIO_HAS_ALIAS_TEMPLATES)+ template <typename T, typename Executor> using associated_immediate_executor_t =   typename associated_immediate_executor<T, Executor>::type; +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+ namespace detail {  template <typename T, typename E, typename = void>@@ -240,19 +248,22 @@  template <typename T, typename E> struct associated_immediate_executor_forwarding_base<T, E,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_immediate_executor<T,           E>::asio_associated_immediate_executor_is_unspecialised,         void       >::value-    >>+    >::type> {   typedef void asio_associated_immediate_executor_is_unspecialised; };  } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \+  || defined(GENERATING_DOCUMENTATION)+ /// Specialisation of associated_immediate_executor for /// @c std::reference_wrapper. template <typename T, typename Executor>@@ -267,12 +278,17 @@    /// Forwards the request to get the executor to the associator specialisation   /// for the unwrapped type @c T.-  static auto get(reference_wrapper<T> t, const Executor& ex) noexcept-    -> decltype(associated_immediate_executor<T, Executor>::get(t.get(), ex))+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      reference_wrapper<T> t, const Executor& ex) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      associated_immediate_executor<T, Executor>::get(t.get(), ex)))   {     return associated_immediate_executor<T, Executor>::get(t.get(), ex);   } };++#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+       //   || defined(GENERATING_DOCUMENTATION)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/associator.hpp view
@@ -2,7 +2,7 @@ // associator.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,7 +23,7 @@  /// Used to generically specialise associators for a type. template <template <typename, typename> class Associator,-    typename T, typename DefaultCandidate, typename _ = void>+    typename T, typename DefaultCandidate> struct associator { };
link/modules/asio-standalone/asio/include/asio/async_result.hpp view
@@ -2,967 +2,1670 @@ // async_result.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_ASYNC_RESULT_HPP-#define ASIO_ASYNC_RESULT_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename T>-struct is_completion_signature : false_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...)> : true_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) &> : true_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) &&> : true_type-{-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) noexcept> : true_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) & noexcept> : true_type-{-};--template <typename R, typename... Args>-struct is_completion_signature<R(Args...) && noexcept> : true_type-{-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename... T>-struct are_completion_signatures : false_type-{-};--template <>-struct are_completion_signatures<>-  : true_type-{-};--template <typename T0>-struct are_completion_signatures<T0>-  : is_completion_signature<T0>-{-};--template <typename T0, typename... TN>-struct are_completion_signatures<T0, TN...>-  : integral_constant<bool, (-      is_completion_signature<T0>::value-        && are_completion_signatures<TN...>::value)>-{-};--} // namespace detail--#if defined(ASIO_HAS_CONCEPTS)--namespace detail {--template <typename T, typename... Args>-ASIO_CONCEPT callable_with = requires(T&& t, Args&&... args)-{-  static_cast<T&&>(t)(static_cast<Args&&>(args)...);-};--template <typename T, typename... Signatures>-struct is_completion_handler_for : false_type-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...)>-  : integral_constant<bool, (callable_with<decay_t<T>, Args...>)>-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) &>-  : integral_constant<bool, (callable_with<decay_t<T>&, Args...>)>-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) &&>-  : integral_constant<bool, (callable_with<decay_t<T>&&, Args...>)>-{-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) noexcept>-  : integral_constant<bool, (callable_with<decay_t<T>, Args...>)>-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) & noexcept>-  : integral_constant<bool, (callable_with<decay_t<T>&, Args...>)>-{-};--template <typename T, typename R, typename... Args>-struct is_completion_handler_for<T, R(Args...) && noexcept>-  : integral_constant<bool, (callable_with<decay_t<T>&&, Args...>)>-{-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename T, typename Signature0, typename... SignatureN>-struct is_completion_handler_for<T, Signature0, SignatureN...>-  : integral_constant<bool, (-      is_completion_handler_for<T, Signature0>::value-        && is_completion_handler_for<T, SignatureN...>::value)>-{-};--} // namespace detail--template <typename T>-ASIO_CONCEPT completion_signature =-  detail::is_completion_signature<T>::value;--#define ASIO_COMPLETION_SIGNATURE \-  ::asio::completion_signature--template <typename T, typename... Signatures>-ASIO_CONCEPT completion_handler_for =-  detail::are_completion_signatures<Signatures...>::value-    && detail::is_completion_handler_for<T, Signatures...>::value;--#define ASIO_COMPLETION_HANDLER_FOR(sig) \-  ::asio::completion_handler_for<sig>-#define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) \-  ::asio::completion_handler_for<sig0, sig1>-#define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) \-  ::asio::completion_handler_for<sig0, sig1, sig2>--#else // defined(ASIO_HAS_CONCEPTS)--#define ASIO_COMPLETION_SIGNATURE typename-#define ASIO_COMPLETION_HANDLER_FOR(sig) typename-#define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) typename-#define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) typename--#endif // defined(ASIO_HAS_CONCEPTS)--namespace detail {--template <typename T>-struct is_lvalue_completion_signature : false_type-{-};--template <typename R, typename... Args>-struct is_lvalue_completion_signature<R(Args...) &> : true_type-{-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename R, typename... Args>-struct is_lvalue_completion_signature<R(Args...) & noexcept> : true_type-{-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename... Signatures>-struct are_any_lvalue_completion_signatures : false_type-{-};--template <typename Sig0>-struct are_any_lvalue_completion_signatures<Sig0>-  : is_lvalue_completion_signature<Sig0>-{-};--template <typename Sig0, typename... SigN>-struct are_any_lvalue_completion_signatures<Sig0, SigN...>-  : integral_constant<bool, (-      is_lvalue_completion_signature<Sig0>::value-        || are_any_lvalue_completion_signatures<SigN...>::value)>-{-};--template <typename T>-struct is_rvalue_completion_signature : false_type-{-};--template <typename R, typename... Args>-struct is_rvalue_completion_signature<R(Args...) &&> : true_type-{-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename R, typename... Args>-struct is_rvalue_completion_signature<R(Args...) && noexcept> : true_type-{-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename... Signatures>-struct are_any_rvalue_completion_signatures : false_type-{-};--template <typename Sig0>-struct are_any_rvalue_completion_signatures<Sig0>-  : is_rvalue_completion_signature<Sig0>-{-};--template <typename Sig0, typename... SigN>-struct are_any_rvalue_completion_signatures<Sig0, SigN...>-  : integral_constant<bool, (-      is_rvalue_completion_signature<Sig0>::value-        || are_any_rvalue_completion_signatures<SigN...>::value)>-{-};--template <typename T>-struct simple_completion_signature;--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...)>-{-  typedef R type(Args...);-};--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) &>-{-  typedef R type(Args...);-};--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) &&>-{-  typedef R type(Args...);-};--# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) noexcept>-{-  typedef R type(Args...);-};--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) & noexcept>-{-  typedef R type(Args...);-};--template <typename R, typename... Args>-struct simple_completion_signature<R(Args...) && noexcept>-{-  typedef R type(Args...);-};--# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--template <typename CompletionToken,-    ASIO_COMPLETION_SIGNATURE... Signatures>-class completion_handler_async_result-{-public:-  typedef CompletionToken completion_handler_type;-  typedef void return_type;--  explicit completion_handler_async_result(completion_handler_type&)-  {-  }--  return_type get()-  {-  }--  template <typename Initiation,-      ASIO_COMPLETION_HANDLER_FOR(Signatures...) RawCompletionToken,-      typename... Args>-  static return_type initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-  {-    static_cast<Initiation&&>(initiation)(-        static_cast<RawCompletionToken&&>(token),-        static_cast<Args&&>(args)...);-  }--private:-  completion_handler_async_result(-      const completion_handler_async_result&) = delete;-  completion_handler_async_result& operator=(-      const completion_handler_async_result&) = delete;-};--} // namespace detail--#if defined(GENERATING_DOCUMENTATION)--/// An interface for customising the behaviour of an initiating function.-/**- * The async_result trait is a customisation point that is used within the- * initiating function for an @ref asynchronous_operation. The trait combines:- *- * @li the completion signature (or signatures) that describe the arguments that- * an asynchronous operation will pass to a completion handler;- *- * @li the @ref completion_token type supplied by the caller; and- *- * @li the operation's internal implementation.- *- * Specialisations of the trait must satisfy the @ref async_result_requirements,- * and are reponsible for determining:- *- * @li the concrete completion handler type to be called at the end of the- * asynchronous operation;- *- * @li the initiating function return type;- *- * @li how the return value of the initiating function is obtained; and- *- * @li how and when to launch the operation by invoking the supplied initiation- * function object.- *- * This template may be specialised for user-defined completion token types.- * The primary template assumes that the CompletionToken is the already a- * concrete completion handler.- *- * @note For backwards compatibility, the primary template implements member- * types and functions that are associated with legacy forms of the async_result- * trait. These are annotated as "Legacy" in the documentation below. User- * specialisations of this trait do not need to implement these in order to- * satisfy the @ref async_result_requirements.- *- * In general, implementers of asynchronous operations should use the- * async_initiate function rather than using the async_result trait directly.- */-template <typename CompletionToken,-    ASIO_COMPLETION_SIGNATURE... Signatures>-class async_result-{-public:-  /// (Legacy.) The concrete completion handler type for the specific signature.-  typedef CompletionToken completion_handler_type;--  /// (Legacy.) The return type of the initiating function.-  typedef void return_type;--  /// (Legacy.) Construct an async result from a given handler.-  /**-   * When using a specalised async_result, the constructor has an opportunity-   * to initialise some state associated with the completion handler, which is-   * then returned from the initiating function.-   */-  explicit async_result(completion_handler_type& h);--  /// (Legacy.) Obtain the value to be returned from the initiating function.-  return_type get();--  /// Initiate the asynchronous operation that will produce the result, and-  /// obtain the value to be returned from the initiating function.-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static return_type initiate(-      Initiation&& initiation,-      RawCompletionToken&& token,-      Args&&... args);--private:-  async_result(const async_result&) = delete;-  async_result& operator=(const async_result&) = delete;-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken,-    ASIO_COMPLETION_SIGNATURE... Signatures>-class async_result :-  public conditional_t<-      detail::are_any_lvalue_completion_signatures<Signatures...>::value-        || !detail::are_any_rvalue_completion_signatures<Signatures...>::value,-      detail::completion_handler_async_result<CompletionToken, Signatures...>,-      async_result<CompletionToken,-        typename detail::simple_completion_signature<Signatures>::type...>-    >-{-public:-  typedef conditional_t<-      detail::are_any_lvalue_completion_signatures<Signatures...>::value-        || !detail::are_any_rvalue_completion_signatures<Signatures...>::value,-      detail::completion_handler_async_result<CompletionToken, Signatures...>,-      async_result<CompletionToken,-        typename detail::simple_completion_signature<Signatures>::type...>-    > base_type;--  using base_type::base_type;--private:-  async_result(const async_result&) = delete;-  async_result& operator=(const async_result&) = delete;-};--template <ASIO_COMPLETION_SIGNATURE... Signatures>-class async_result<void, Signatures...>-{-  // Empty.-};--#endif // defined(GENERATING_DOCUMENTATION)--/// Helper template to deduce the handler type from a CompletionToken, capture-/// a local copy of the handler, and then create an async_result for the-/// handler.-template <typename CompletionToken,-    ASIO_COMPLETION_SIGNATURE... Signatures>-struct async_completion-{-  /// The real handler type to be used for the asynchronous operation.-  typedef typename asio::async_result<-    decay_t<CompletionToken>, Signatures...>::completion_handler_type-      completion_handler_type;--  /// Constructor.-  /**-   * The constructor creates the concrete completion handler and makes the link-   * between the handler and the asynchronous result.-   */-  explicit async_completion(CompletionToken& token)-    : completion_handler(static_cast<conditional_t<-        is_same<CompletionToken, completion_handler_type>::value,-        completion_handler_type&, CompletionToken&&>>(token)),-      result(completion_handler)-  {-  }--  /// A copy of, or reference to, a real handler object.-  conditional_t<-    is_same<CompletionToken, completion_handler_type>::value,-    completion_handler_type&, completion_handler_type> completion_handler;--  /// The result of the asynchronous operation's initiating function.-  async_result<decay_t<CompletionToken>, Signatures...> result;-};--namespace detail {--struct async_result_memfns_base-{-  void initiate();-};--template <typename T>-struct async_result_memfns_derived-  : T, async_result_memfns_base-{-};--template <typename T, T>-struct async_result_memfns_check-{-};--template <typename>-char (&async_result_initiate_memfn_helper(...))[2];--template <typename T>-char async_result_initiate_memfn_helper(-    async_result_memfns_check<-      void (async_result_memfns_base::*)(),-      &async_result_memfns_derived<T>::initiate>*);--template <typename CompletionToken,-    ASIO_COMPLETION_SIGNATURE... Signatures>-struct async_result_has_initiate_memfn-  : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<-      async_result<decay_t<CompletionToken>, Signatures...>-    >(0)) != 1>-{-};--} // namespace detail--#if defined(GENERATING_DOCUMENTATION)-# define ASIO_INITFN_RESULT_TYPE(ct, sig) \-  void_or_deduced-# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \-  void_or_deduced-# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \-  void_or_deduced-#else-# define ASIO_INITFN_RESULT_TYPE(ct, sig) \-  typename ::asio::async_result< \-    typename ::asio::decay<ct>::type, sig>::return_type-# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \-  typename ::asio::async_result< \-    typename ::asio::decay<ct>::type, sig0, sig1>::return_type-# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \-  typename ::asio::async_result< \-    typename ::asio::decay<ct>::type, sig0, sig1, sig2>::return_type-#define ASIO_HANDLER_TYPE(ct, sig) \-  typename ::asio::async_result< \-    typename ::asio::decay<ct>::type, sig>::completion_handler_type-#define ASIO_HANDLER_TYPE2(ct, sig0, sig1) \-  typename ::asio::async_result< \-    typename ::asio::decay<ct>::type, \-      sig0, sig1>::completion_handler_type-#define ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \-  typename ::asio::async_result< \-    typename ::asio::decay<ct>::type, \-      sig0, sig1, sig2>::completion_handler_type-#endif--#if defined(GENERATING_DOCUMENTATION)-# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \-  auto-#elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)-# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \-  auto-#else-# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \-  ASIO_INITFN_RESULT_TYPE(ct, sig)-# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \-  ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)-# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \-  ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)-#endif--#if defined(GENERATING_DOCUMENTATION)-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)-#elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)-#else-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \-  auto-# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr) -> decltype expr-#endif--#if defined(GENERATING_DOCUMENTATION)-# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \-  void_or_deduced-# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \-  void_or_deduced-# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \-  void_or_deduced-#else-# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \-  decltype expr-# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \-  decltype expr-# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \-  decltype expr-#endif--#if defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken,-    completion_signature... Signatures,-    typename Initiation, typename... Args>-void_or_deduced async_initiate(-    Initiation&& initiation,-    type_identity_t<CompletionToken>& token,-    Args&&... args);--#else // defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken,-    ASIO_COMPLETION_SIGNATURE... Signatures,-    typename Initiation, typename... Args>-inline auto async_initiate(Initiation&& initiation,-    type_identity_t<CompletionToken>& token, Args&&... args)-  -> decltype(enable_if_t<-    enable_if_t<-      detail::are_completion_signatures<Signatures...>::value,-      detail::async_result_has_initiate_memfn<-        CompletionToken, Signatures...>>::value,-    async_result<decay_t<CompletionToken>, Signatures...>>::initiate(-      static_cast<Initiation&&>(initiation),-      static_cast<CompletionToken&&>(token),-      static_cast<Args&&>(args)...))-{-  return async_result<decay_t<CompletionToken>, Signatures...>::initiate(-      static_cast<Initiation&&>(initiation),-      static_cast<CompletionToken&&>(token),-      static_cast<Args&&>(args)...);-}--template <-    ASIO_COMPLETION_SIGNATURE... Signatures,-    typename CompletionToken, typename Initiation, typename... Args>-inline auto async_initiate(Initiation&& initiation,-    CompletionToken&& token, Args&&... args)-  -> decltype(enable_if_t<-    enable_if_t<-      detail::are_completion_signatures<Signatures...>::value,-      detail::async_result_has_initiate_memfn<-        CompletionToken, Signatures...>>::value,-    async_result<decay_t<CompletionToken>, Signatures...>>::initiate(-      static_cast<Initiation&&>(initiation),-      static_cast<CompletionToken&&>(token),-      static_cast<Args&&>(args)...))-{-  return async_result<decay_t<CompletionToken>, Signatures...>::initiate(-      static_cast<Initiation&&>(initiation),-      static_cast<CompletionToken&&>(token),-      static_cast<Args&&>(args)...);-}--template <typename CompletionToken,-    ASIO_COMPLETION_SIGNATURE... Signatures,-    typename Initiation, typename... Args>-inline typename enable_if_t<-    !enable_if_t<-      detail::are_completion_signatures<Signatures...>::value,-      detail::async_result_has_initiate_memfn<-        CompletionToken, Signatures...>>::value,-    async_result<decay_t<CompletionToken>, Signatures...>-  >::return_type-async_initiate(Initiation&& initiation,-    type_identity_t<CompletionToken>& token, Args&&... args)-{-  async_completion<CompletionToken, Signatures...> completion(token);--  static_cast<Initiation&&>(initiation)(-      static_cast<-        typename async_result<decay_t<CompletionToken>,-          Signatures...>::completion_handler_type&&>(-            completion.completion_handler),-      static_cast<Args&&>(args)...);--  return completion.result.get();-}--template <ASIO_COMPLETION_SIGNATURE... Signatures,-    typename CompletionToken, typename Initiation, typename... Args>-inline typename enable_if_t<-    !enable_if_t<-      detail::are_completion_signatures<Signatures...>::value,-      detail::async_result_has_initiate_memfn<-        CompletionToken, Signatures...>>::value,-    async_result<decay_t<CompletionToken>, Signatures...>-  >::return_type-async_initiate(Initiation&& initiation, CompletionToken&& token, Args&&... args)-{-  async_completion<CompletionToken, Signatures...> completion(token);--  static_cast<Initiation&&>(initiation)(-      static_cast<-        typename async_result<decay_t<CompletionToken>,-          Signatures...>::completion_handler_type&&>(-            completion.completion_handler),-      static_cast<Args&&>(args)...);--  return completion.result.get();-}--#endif // defined(GENERATING_DOCUMENTATION)--#if defined(ASIO_HAS_CONCEPTS)--namespace detail {--template <typename... Signatures>-struct initiation_archetype-{-  template <completion_handler_for<Signatures...> CompletionHandler>-  void operator()(CompletionHandler&&) const-  {-  }-};--} // namespace detail--template <typename T, typename... Signatures>-ASIO_CONCEPT completion_token_for =-  detail::are_completion_signatures<Signatures...>::value-  &&-  requires(T&& t)-  {-    async_initiate<T, Signatures...>(-        detail::initiation_archetype<Signatures...>{}, t);-  };--#define ASIO_COMPLETION_TOKEN_FOR(sig) \-  ::asio::completion_token_for<sig>-#define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) \-  ::asio::completion_token_for<sig0, sig1>-#define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) \-  ::asio::completion_token_for<sig0, sig1, sig2>--#else // defined(ASIO_HAS_CONCEPTS)--#define ASIO_COMPLETION_TOKEN_FOR(sig) typename-#define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) typename-#define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) typename--#endif // defined(ASIO_HAS_CONCEPTS)--namespace detail {--struct async_operation_probe {};-struct async_operation_probe_result {};--template <typename Call, typename = void>-struct is_async_operation_call : false_type-{-};--template <typename Call>-struct is_async_operation_call<Call,-    void_t<-      enable_if_t<-        is_same<-          result_of_t<Call>,-          async_operation_probe_result-        >::value-      >-    >-  > : true_type-{-};--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <typename... Signatures>-class async_result<detail::async_operation_probe, Signatures...>-{-public:-  typedef detail::async_operation_probe_result return_type;--  template <typename Initiation, typename... InitArgs>-  static return_type initiate(Initiation&&,-      detail::async_operation_probe, InitArgs&&...)-  {-    return return_type();-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#if defined(GENERATING_DOCUMENTATION)--/// The is_async_operation trait detects whether a type @c T and arguments-/// @c Args... may be used to initiate an asynchronous operation.-/**- * Class template @c is_async_operation is a trait is derived from @c true_type- * if the expression <tt>T(Args..., token)</tt> initiates an asynchronous- * operation, where @c token is an unspecified completion token type. Otherwise,- * @c is_async_operation is derived from @c false_type.- */-template <typename T, typename... Args>-struct is_async_operation : integral_constant<bool, automatically_determined>-{-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename T, typename... Args>-struct is_async_operation :-  detail::is_async_operation_call<-    T(Args..., detail::async_operation_probe)>-{-};--#endif // defined(GENERATING_DOCUMENTATION)--#if defined(ASIO_HAS_CONCEPTS)--template <typename T, typename... Args>-ASIO_CONCEPT async_operation = is_async_operation<T, Args...>::value;--#define ASIO_ASYNC_OPERATION \-  ::asio::async_operation-#define ASIO_ASYNC_OPERATION1(a0) \-  ::asio::async_operation<a0>-#define ASIO_ASYNC_OPERATION2(a0, a1) \-  ::asio::async_operation<a0, a1>-#define ASIO_ASYNC_OPERATION3(a0, a1, a2) \-  ::asio::async_operation<a0, a1, a2>--#else // defined(ASIO_HAS_CONCEPTS)--#define ASIO_ASYNC_OPERATION typename-#define ASIO_ASYNC_OPERATION1(a0) typename-#define ASIO_ASYNC_OPERATION2(a0, a1) typename-#define ASIO_ASYNC_OPERATION3(a0, a1, a2) typename--#endif // defined(ASIO_HAS_CONCEPTS)--namespace detail {--struct completion_signature_probe {};--template <typename... T>-struct completion_signature_probe_result-{-  template <template <typename...> class Op>-  struct apply-  {-    typedef Op<T...> type;-  };-};--template <typename T>-struct completion_signature_probe_result<T>-{-  typedef T type;--  template <template <typename...> class Op>-  struct apply-  {-    typedef Op<T> type;-  };-};--template <>-struct completion_signature_probe_result<void>-{-  template <template <typename...> class Op>-  struct apply-  {-    typedef Op<> type;-  };-};--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <typename... Signatures>-class async_result<detail::completion_signature_probe, Signatures...>-{-public:-  typedef detail::completion_signature_probe_result<Signatures...> return_type;--  template <typename Initiation, typename... InitArgs>-  static return_type initiate(Initiation&&,-      detail::completion_signature_probe, InitArgs&&...)-  {-    return return_type();-  }-};--template <typename Signature>-class async_result<detail::completion_signature_probe, Signature>-{-public:-  typedef detail::completion_signature_probe_result<Signature> return_type;--  template <typename Initiation, typename... InitArgs>-  static return_type initiate(Initiation&&,-      detail::completion_signature_probe, InitArgs&&...)-  {-    return return_type();-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#if defined(GENERATING_DOCUMENTATION)--/// The completion_signature_of trait determines the completion signature-/// of an asynchronous operation.-/**- * Class template @c completion_signature_of is a trait with a member type- * alias @c type that denotes the completion signature of the asynchronous- * operation initiated by the expression <tt>T(Args..., token)</tt> operation,- * where @c token is an unspecified completion token type. If the asynchronous- * operation does not have exactly one completion signature, the instantion of- * the trait is well-formed but the member type alias @c type is omitted. If- * the expression <tt>T(Args..., token)</tt> is not an asynchronous operation- * then use of the trait is ill-formed.- */-template <typename T, typename... Args>-struct completion_signature_of-{-  typedef automatically_determined type;-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename T, typename... Args>-struct completion_signature_of :-  result_of_t<T(Args..., detail::completion_signature_probe)>-{-};--#endif // defined(GENERATING_DOCUMENTATION)--template <typename T, typename... Args>-using completion_signature_of_t =-  typename completion_signature_of<T, Args...>::type;--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/default_completion_token.hpp"+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_ASYNC_RESULT_HPP+#define ASIO_ASYNC_RESULT_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++#if defined(ASIO_HAS_CONCEPTS) \+  && defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  && defined(ASIO_HAS_DECLTYPE)++namespace detail {++template <typename T>+struct is_completion_signature : false_type+{+};++template <typename R, typename... Args>+struct is_completion_signature<R(Args...)> : true_type+{+};++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) &> : true_type+{+};++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) &&> : true_type+{+};++# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) noexcept> : true_type+{+};++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) & noexcept> : true_type+{+};++template <typename R, typename... Args>+struct is_completion_signature<R(Args...) && noexcept> : true_type+{+};++# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename... T>+struct are_completion_signatures : false_type+{+};++template <typename T0>+struct are_completion_signatures<T0>+  : is_completion_signature<T0>+{+};++template <typename T0, typename... TN>+struct are_completion_signatures<T0, TN...>+  : integral_constant<bool, (+      is_completion_signature<T0>::value+        && are_completion_signatures<TN...>::value)>+{+};++template <typename T, typename... Args>+ASIO_CONCEPT callable_with = requires(T&& t, Args&&... args)+{+  static_cast<T&&>(t)(static_cast<Args&&>(args)...);+};++template <typename T, typename... Signatures>+struct is_completion_handler_for : false_type+{+};++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...)>+  : integral_constant<bool, (callable_with<T, Args...>)>+{+};++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) &>+  : integral_constant<bool, (callable_with<T&, Args...>)>+{+};++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) &&>+  : integral_constant<bool, (callable_with<T&&, Args...>)>+{+};++# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) noexcept>+  : integral_constant<bool, (callable_with<T, Args...>)>+{+};++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) & noexcept>+  : integral_constant<bool, (callable_with<T&, Args...>)>+{+};++template <typename T, typename R, typename... Args>+struct is_completion_handler_for<T, R(Args...) && noexcept>+  : integral_constant<bool, (callable_with<T&&, Args...>)>+{+};++# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename T, typename Signature0, typename... SignatureN>+struct is_completion_handler_for<T, Signature0, SignatureN...>+  : integral_constant<bool, (+      is_completion_handler_for<T, Signature0>::value+        && is_completion_handler_for<T, SignatureN...>::value)>+{+};++} // namespace detail++template <typename T>+ASIO_CONCEPT completion_signature =+  detail::is_completion_signature<T>::value;++#define ASIO_COMPLETION_SIGNATURE \+  ::asio::completion_signature++template <typename T, typename... Signatures>+ASIO_CONCEPT completion_handler_for =+  detail::are_completion_signatures<Signatures...>::value+    && detail::is_completion_handler_for<T, Signatures...>::value;++#define ASIO_COMPLETION_HANDLER_FOR(sig) \+  ::asio::completion_handler_for<sig>+#define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) \+  ::asio::completion_handler_for<sig0, sig1>+#define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) \+  ::asio::completion_handler_for<sig0, sig1, sig2>++#else // defined(ASIO_HAS_CONCEPTS)+      //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)+      //   && defined(ASIO_HAS_DECLTYPE)++#define ASIO_COMPLETION_SIGNATURE typename+#define ASIO_COMPLETION_HANDLER_FOR(sig) typename+#define ASIO_COMPLETION_HANDLER_FOR2(sig0, sig1) typename+#define ASIO_COMPLETION_HANDLER_FOR3(sig0, sig1, sig2) typename++#endif // defined(ASIO_HAS_CONCEPTS)+       //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   && defined(ASIO_HAS_DECLTYPE)++namespace detail {++template <typename T>+struct is_simple_completion_signature : false_type+{+};++template <typename T>+struct simple_completion_signature;++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename R, typename... Args>+struct is_simple_completion_signature<R(Args...)> : true_type+{+};++template <typename... Signatures>+struct are_simple_completion_signatures : false_type+{+};++template <typename Sig0>+struct are_simple_completion_signatures<Sig0>+  : is_simple_completion_signature<Sig0>+{+};++template <typename Sig0, typename... SigN>+struct are_simple_completion_signatures<Sig0, SigN...>+  : integral_constant<bool, (+      is_simple_completion_signature<Sig0>::value+        && are_simple_completion_signatures<SigN...>::value)>+{+};++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...)>+{+  typedef R type(Args...);+};++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) &>+{+  typedef R type(Args...);+};++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) &&>+{+  typedef R type(Args...);+};++# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) noexcept>+{+  typedef R type(Args...);+};++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) & noexcept>+{+  typedef R type(Args...);+};++template <typename R, typename... Args>+struct simple_completion_signature<R(Args...) && noexcept>+{+  typedef R type(Args...);+};++# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename R>+struct is_simple_completion_signature<R()> : true_type+{+};++#define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct is_simple_completion_signature<R(ASIO_VARIADIC_TARGS(n))> \+    : true_type \+  { \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)+#undef ASIO_PRIVATE_SIMPLE_SIG_DEF++template <typename Sig0 = void, typename Sig1 = void,+    typename Sig2 = void, typename = void>+struct are_simple_completion_signatures : false_type+{+};++template <typename Sig0>+struct are_simple_completion_signatures<Sig0>+  : is_simple_completion_signature<Sig0>+{+};++template <typename Sig0, typename Sig1>+struct are_simple_completion_signatures<Sig0, Sig1>+  : integral_constant<bool,+      (is_simple_completion_signature<Sig0>::value+        && is_simple_completion_signature<Sig1>::value)>+{+};++template <typename Sig0, typename Sig1, typename Sig2>+struct are_simple_completion_signatures<Sig0, Sig1, Sig2>+  : integral_constant<bool,+      (is_simple_completion_signature<Sig0>::value+        && is_simple_completion_signature<Sig1>::value+        && is_simple_completion_signature<Sig2>::value)>+{+};++template <>+struct simple_completion_signature<void>+{+  typedef void type;+};++template <typename R>+struct simple_completion_signature<R()>+{+  typedef R type();+};++#define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct simple_completion_signature<R(ASIO_VARIADIC_TARGS(n))> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)); \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)+#undef ASIO_PRIVATE_SIMPLE_SIG_DEF++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename R>+struct simple_completion_signature<R() &>+{+  typedef R type();+};++template <typename R>+struct simple_completion_signature<R() &&>+{+  typedef R type();+};++#define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct simple_completion_signature< \+    R(ASIO_VARIADIC_TARGS(n)) &> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)); \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct simple_completion_signature< \+    R(ASIO_VARIADIC_TARGS(n)) &&> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)); \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)+#undef ASIO_PRIVATE_SIMPLE_SIG_DEF++# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename R>+struct simple_completion_signature<R() noexcept>+{+  typedef R type();+};++template <typename R>+struct simple_completion_signature<R() & noexcept>+{+  typedef R type();+};++template <typename R>+struct simple_completion_signature<R() && noexcept>+{+  typedef R type();+};++#define ASIO_PRIVATE_SIMPLE_SIG_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct simple_completion_signature< \+    R(ASIO_VARIADIC_TARGS(n)) noexcept> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)); \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct simple_completion_signature< \+    R(ASIO_VARIADIC_TARGS(n)) & noexcept> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)); \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct simple_completion_signature< \+    R(ASIO_VARIADIC_TARGS(n)) && noexcept> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)); \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SIMPLE_SIG_DEF)+#undef ASIO_PRIVATE_SIMPLE_SIG_DEF++# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)++# define ASIO_COMPLETION_SIGNATURES_TPARAMS \+    ASIO_COMPLETION_SIGNATURE... Signatures++# define ASIO_COMPLETION_SIGNATURES_TSPECPARAMS \+    ASIO_COMPLETION_SIGNATURE... Signatures++# define ASIO_COMPLETION_SIGNATURES_TARGS Signatures...++# define ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS \+    typename asio::detail::simple_completion_signature< \+      Signatures>::type...++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+      //   || defined(GENERATING_DOCUMENTATION)++# define ASIO_COMPLETION_SIGNATURES_TPARAMS \+    typename Sig0 = void, \+    typename Sig1 = void, \+    typename Sig2 = void++# define ASIO_COMPLETION_SIGNATURES_TSPECPARAMS \+    typename Sig0, \+    typename Sig1, \+    typename Sig2++# define ASIO_COMPLETION_SIGNATURES_TARGS Sig0, Sig1, Sig2++# define ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS \+    typename ::asio::detail::simple_completion_signature<Sig0>::type, \+    typename ::asio::detail::simple_completion_signature<Sig1>::type, \+    typename ::asio::detail::simple_completion_signature<Sig2>::type++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+class completion_handler_async_result+{+public:+  typedef CompletionToken completion_handler_type;+  typedef void return_type;++  explicit completion_handler_async_result(completion_handler_type&)+  {+  }++  return_type get()+  {+  }++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename Initiation,+      ASIO_COMPLETION_HANDLER_FOR(Signatures...) RawCompletionToken,+      typename... Args>+  static return_type initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)+  {+    ASIO_MOVE_CAST(Initiation)(initiation)(+        ASIO_MOVE_CAST(RawCompletionToken)(token),+        ASIO_MOVE_CAST(Args)(args)...);+  }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename Initiation, typename RawCompletionToken>+  static return_type initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token)+  {+    ASIO_MOVE_CAST(Initiation)(initiation)(+        ASIO_MOVE_CAST(RawCompletionToken)(token));+  }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, \+      typename RawCompletionToken, \+      ASIO_VARIADIC_TPARAMS(n)> \+  static return_type initiate( \+      ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_MOVE_ARG(RawCompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    ASIO_MOVE_CAST(Initiation)(initiation)( \+        ASIO_MOVE_CAST(RawCompletionToken)(token), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+  completion_handler_async_result(+      const completion_handler_async_result&) ASIO_DELETED;+  completion_handler_async_result& operator=(+      const completion_handler_async_result&) ASIO_DELETED;+};++} // namespace detail++#if defined(GENERATING_DOCUMENTATION)++/// An interface for customising the behaviour of an initiating function.+/**+ * The async_result traits class is used for determining:+ *+ * @li the concrete completion handler type to be called at the end of the+ * asynchronous operation;+ *+ * @li the initiating function return type; and+ *+ * @li how the return value of the initiating function is obtained.+ *+ * The trait allows the handler and return types to be determined at the point+ * where the specific completion handler signature is known.+ *+ * This template may be specialised for user-defined completion token types.+ * The primary template assumes that the CompletionToken is the completion+ * handler.+ */+template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+class async_result+{+public:+  /// The concrete completion handler type for the specific signature.+  typedef CompletionToken completion_handler_type;++  /// The return type of the initiating function.+  typedef void return_type;++  /// Construct an async result from a given handler.+  /**+   * When using a specalised async_result, the constructor has an opportunity+   * to initialise some state associated with the completion handler, which is+   * then returned from the initiating function.+   */+  explicit async_result(completion_handler_type& h);++  /// Obtain the value to be returned from the initiating function.+  return_type get();++  /// Initiate the asynchronous operation that will produce the result, and+  /// obtain the value to be returned from the initiating function.+  template <typename Initiation, typename RawCompletionToken, typename... Args>+  static return_type initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args);++private:+  async_result(const async_result&) ASIO_DELETED;+  async_result& operator=(const async_result&) ASIO_DELETED;+};++#else // defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+class async_result :+  public conditional<+      detail::are_simple_completion_signatures<+        ASIO_COMPLETION_SIGNATURES_TARGS>::value,+      detail::completion_handler_async_result<+        CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>,+      async_result<CompletionToken,+        ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS>+    >::type+{+public:+  typedef typename conditional<+      detail::are_simple_completion_signatures<+        ASIO_COMPLETION_SIGNATURES_TARGS>::value,+      detail::completion_handler_async_result<+        CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>,+      async_result<CompletionToken,+        ASIO_COMPLETION_SIGNATURES_TSIMPLEARGS>+    >::type base_type;++  using base_type::base_type;++private:+  async_result(const async_result&) ASIO_DELETED;+  async_result& operator=(const async_result&) ASIO_DELETED;+};++#else // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+class async_result :+  public detail::completion_handler_async_result<+    CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>+{+public:+  explicit async_result(CompletionToken& h)+    : detail::completion_handler_async_result<+        CompletionToken, ASIO_COMPLETION_SIGNATURES_TARGS>(h)+  {+  }++private:+  async_result(const async_result&) ASIO_DELETED;+  async_result& operator=(const async_result&) ASIO_DELETED;+};++#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <ASIO_COMPLETION_SIGNATURES_TSPECPARAMS>+class async_result<void, ASIO_COMPLETION_SIGNATURES_TARGS>+{+  // Empty.+};++#endif // defined(GENERATING_DOCUMENTATION)++/// Helper template to deduce the handler type from a CompletionToken, capture+/// a local copy of the handler, and then create an async_result for the+/// handler.+template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+struct async_completion+{+  /// The real handler type to be used for the asynchronous operation.+  typedef typename asio::async_result<+    typename decay<CompletionToken>::type,+      ASIO_COMPLETION_SIGNATURES_TARGS>::completion_handler_type+        completion_handler_type;++#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+  /// Constructor.+  /**+   * The constructor creates the concrete completion handler and makes the link+   * between the handler and the asynchronous result.+   */+  explicit async_completion(CompletionToken& token)+    : completion_handler(static_cast<typename conditional<+        is_same<CompletionToken, completion_handler_type>::value,+        completion_handler_type&, CompletionToken&&>::type>(token)),+      result(completion_handler)+  {+  }+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+  explicit async_completion(typename decay<CompletionToken>::type& token)+    : completion_handler(token),+      result(completion_handler)+  {+  }++  explicit async_completion(const typename decay<CompletionToken>::type& token)+    : completion_handler(token),+      result(completion_handler)+  {+  }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++  /// A copy of, or reference to, a real handler object.+#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+  typename conditional<+    is_same<CompletionToken, completion_handler_type>::value,+    completion_handler_type&, completion_handler_type>::type completion_handler;+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+  completion_handler_type completion_handler;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++  /// The result of the asynchronous operation's initiating function.+  async_result<typename decay<CompletionToken>::type,+    ASIO_COMPLETION_SIGNATURES_TARGS> result;+};++namespace detail {++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+struct async_result_helper+  : async_result<typename decay<CompletionToken>::type,+      ASIO_COMPLETION_SIGNATURES_TARGS>+{+};++struct async_result_memfns_base+{+  void initiate();+};++template <typename T>+struct async_result_memfns_derived+  : T, async_result_memfns_base+{+};++template <typename T, T>+struct async_result_memfns_check+{+};++template <typename>+char (&async_result_initiate_memfn_helper(...))[2];++template <typename T>+char async_result_initiate_memfn_helper(+    async_result_memfns_check<+      void (async_result_memfns_base::*)(),+      &async_result_memfns_derived<T>::initiate>*);++template <typename CompletionToken, ASIO_COMPLETION_SIGNATURES_TPARAMS>+struct async_result_has_initiate_memfn+  : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<+      async_result<typename decay<CompletionToken>::type,+        ASIO_COMPLETION_SIGNATURES_TARGS>+    >(0)) != 1>+{+};++} // namespace detail++#if defined(GENERATING_DOCUMENTATION)+# define ASIO_INITFN_RESULT_TYPE(ct, sig) \+  void_or_deduced+# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \+  void_or_deduced+# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \+  void_or_deduced+#elif defined(_MSC_VER) && (_MSC_VER < 1500)+# define ASIO_INITFN_RESULT_TYPE(ct, sig) \+  typename ::asio::detail::async_result_helper< \+    ct, sig>::return_type+# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \+  typename ::asio::detail::async_result_helper< \+    ct, sig0, sig1>::return_type+# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \+  typename ::asio::detail::async_result_helper< \+    ct, sig0, sig1, sig2>::return_type+#define ASIO_HANDLER_TYPE(ct, sig) \+  typename ::asio::detail::async_result_helper< \+    ct, sig>::completion_handler_type+#define ASIO_HANDLER_TYPE2(ct, sig0, sig1) \+  typename ::asio::detail::async_result_helper< \+    ct, sig0, sig1>::completion_handler_type+#define ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \+  typename ::asio::detail::async_result_helper< \+    ct, sig0, sig1, sig2>::completion_handler_type+#else+# define ASIO_INITFN_RESULT_TYPE(ct, sig) \+  typename ::asio::async_result< \+    typename ::asio::decay<ct>::type, sig>::return_type+# define ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1) \+  typename ::asio::async_result< \+    typename ::asio::decay<ct>::type, sig0, sig1>::return_type+# define ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2) \+  typename ::asio::async_result< \+    typename ::asio::decay<ct>::type, sig0, sig1, sig2>::return_type+#define ASIO_HANDLER_TYPE(ct, sig) \+  typename ::asio::async_result< \+    typename ::asio::decay<ct>::type, sig>::completion_handler_type+#define ASIO_HANDLER_TYPE2(ct, sig0, sig1) \+  typename ::asio::async_result< \+    typename ::asio::decay<ct>::type, \+      sig0, sig1>::completion_handler_type+#define ASIO_HANDLER_TYPE3(ct, sig0, sig1, sig2) \+  typename ::asio::async_result< \+    typename ::asio::decay<ct>::type, \+      sig0, sig1, sig2>::completion_handler_type+#endif++#if defined(GENERATING_DOCUMENTATION)+# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \+  auto+#elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)+# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \+  auto+#else+# define ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \+  ASIO_INITFN_RESULT_TYPE(ct, sig)+# define ASIO_INITFN_AUTO_RESULT_TYPE2(ct, sig0, sig1) \+  ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)+# define ASIO_INITFN_AUTO_RESULT_TYPE3(ct, sig0, sig1, sig2) \+  ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)+#endif++#if defined(GENERATING_DOCUMENTATION)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)+#elif defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)+#elif defined(ASIO_HAS_DECLTYPE)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \+  auto+# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr) -> decltype expr+#else+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ct, sig) \+  ASIO_INITFN_RESULT_TYPE(ct, sig)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX2(ct, sig0, sig1) \+  ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)+# define ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX3(ct, sig0, sig1, sig2) \+  ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)+# define ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(expr)+#endif++#if defined(GENERATING_DOCUMENTATION)+# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \+  void_or_deduced+# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \+  void_or_deduced+# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \+  void_or_deduced+#elif defined(ASIO_HAS_DECLTYPE)+# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \+  decltype expr+# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \+  decltype expr+# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \+  decltype expr+#else+# define ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \+  ASIO_INITFN_RESULT_TYPE(ct, sig)+# define ASIO_INITFN_DEDUCED_RESULT_TYPE2(ct, sig0, sig1, expr) \+  ASIO_INITFN_RESULT_TYPE2(ct, sig0, sig1)+# define ASIO_INITFN_DEDUCED_RESULT_TYPE3(ct, sig0, sig1, sig2, expr) \+  ASIO_INITFN_RESULT_TYPE3(ct, sig0, sig1, sig2)+#endif++#if defined(GENERATING_DOCUMENTATION)++template <typename CompletionToken,+    completion_signature... Signatures,+    typename Initiation, typename... Args>+void_or_deduced async_initiate(+    ASIO_MOVE_ARG(Initiation) initiation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),+    ASIO_MOVE_ARG(Args)... args);++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename CompletionToken,+    ASIO_COMPLETION_SIGNATURE... Signatures,+    typename Initiation, typename... Args>+inline typename constraint<+    detail::async_result_has_initiate_memfn<+      CompletionToken, Signatures...>::value,+    ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signatures...,+      (async_result<typename decay<CompletionToken>::type,+        Signatures...>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),+          declval<ASIO_MOVE_ARG(CompletionToken)>(),+          declval<ASIO_MOVE_ARG(Args)>()...)))>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,+    ASIO_MOVE_ARG(Args)... args)+{+  return async_result<typename decay<CompletionToken>::type,+    Signatures...>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),+      ASIO_MOVE_CAST(CompletionToken)(token),+      ASIO_MOVE_CAST(Args)(args)...);+}++template <typename CompletionToken,+    ASIO_COMPLETION_SIGNATURE... Signatures,+    typename Initiation, typename... Args>+inline typename constraint<+    !detail::async_result_has_initiate_memfn<+      CompletionToken, Signatures...>::value,+    ASIO_INITFN_RESULT_TYPE(CompletionToken, Signatures...)>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,+    ASIO_MOVE_ARG(Args)... args)+{+  async_completion<CompletionToken, Signatures...> completion(token);++  ASIO_MOVE_CAST(Initiation)(initiation)(+      ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,+        Signatures...))(completion.completion_handler),+      ASIO_MOVE_CAST(Args)(args)...);++  return completion.result.get();+}++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename CompletionToken,+    ASIO_COMPLETION_SIGNATURE Sig0,+    typename Initiation>+inline typename constraint<+    detail::async_result_has_initiate_memfn<+      CompletionToken, Sig0>::value,+    ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Sig0,+      (async_result<typename decay<CompletionToken>::type,+        Sig0>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),+          declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+  return async_result<typename decay<CompletionToken>::type,+    Sig0>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),+      ASIO_MOVE_CAST(CompletionToken)(token));+}++template <typename CompletionToken,+    ASIO_COMPLETION_SIGNATURE Sig0,+    ASIO_COMPLETION_SIGNATURE Sig1,+    typename Initiation>+inline typename constraint<+    detail::async_result_has_initiate_memfn<+      CompletionToken, Sig0, Sig1>::value,+    ASIO_INITFN_DEDUCED_RESULT_TYPE2(CompletionToken, Sig0, Sig1,+      (async_result<typename decay<CompletionToken>::type,+        Sig0, Sig1>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),+          declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+  return async_result<typename decay<CompletionToken>::type,+    Sig0, Sig1>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),+      ASIO_MOVE_CAST(CompletionToken)(token));+}++template <typename CompletionToken,+    ASIO_COMPLETION_SIGNATURE Sig0,+    ASIO_COMPLETION_SIGNATURE Sig1,+    ASIO_COMPLETION_SIGNATURE Sig2,+    typename Initiation>+inline typename constraint<+    detail::async_result_has_initiate_memfn<+      CompletionToken, Sig0, Sig1, Sig2>::value,+    ASIO_INITFN_DEDUCED_RESULT_TYPE3(CompletionToken, Sig0, Sig1, Sig2,+      (async_result<typename decay<CompletionToken>::type,+        Sig0, Sig1, Sig2>::initiate(declval<ASIO_MOVE_ARG(Initiation)>(),+          declval<ASIO_MOVE_ARG(CompletionToken)>())))>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+  return async_result<typename decay<CompletionToken>::type,+    Sig0, Sig1, Sig2>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),+      ASIO_MOVE_CAST(CompletionToken)(token));+}++template <typename CompletionToken,+    ASIO_COMPLETION_SIGNATURE Sig0,+    typename Initiation>+inline typename constraint<+    !detail::async_result_has_initiate_memfn<+      CompletionToken, Sig0>::value,+    ASIO_INITFN_RESULT_TYPE(CompletionToken, Sig0)>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+  async_completion<CompletionToken, Sig0> completion(token);++  ASIO_MOVE_CAST(Initiation)(initiation)(+      ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,+        Sig0))(completion.completion_handler));++  return completion.result.get();+}++template <typename CompletionToken,+    ASIO_COMPLETION_SIGNATURE Sig0,+    ASIO_COMPLETION_SIGNATURE Sig1,+    typename Initiation>+inline typename constraint<+    !detail::async_result_has_initiate_memfn<+      CompletionToken, Sig0, Sig1>::value,+    ASIO_INITFN_RESULT_TYPE2(CompletionToken, Sig0, Sig1)>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+  async_completion<CompletionToken, Sig0, Sig1> completion(token);++  ASIO_MOVE_CAST(Initiation)(initiation)(+      ASIO_MOVE_CAST(ASIO_HANDLER_TYPE2(CompletionToken,+        Sig0, Sig1))(completion.completion_handler));++  return completion.result.get();+}++template <typename CompletionToken,+    ASIO_COMPLETION_SIGNATURE Sig0,+    ASIO_COMPLETION_SIGNATURE Sig1,+    ASIO_COMPLETION_SIGNATURE Sig2,+    typename Initiation>+inline typename constraint<+    !detail::async_result_has_initiate_memfn<+      CompletionToken, Sig0, Sig1, Sig2>::value,+    ASIO_INITFN_RESULT_TYPE3(CompletionToken, Sig0, Sig1, Sig2)>::type+async_initiate(ASIO_MOVE_ARG(Initiation) initiation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+{+  async_completion<CompletionToken, Sig0, Sig1, Sig2> completion(token);++  ASIO_MOVE_CAST(Initiation)(initiation)(+      ASIO_MOVE_CAST(ASIO_HANDLER_TYPE3(CompletionToken,+        Sig0, Sig1, Sig2))(completion.completion_handler));++  return completion.result.get();+}++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename CompletionToken, \+      ASIO_COMPLETION_SIGNATURE Sig0, \+      typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+  inline typename constraint< \+      detail::async_result_has_initiate_memfn< \+        CompletionToken, Sig0>::value, \+      ASIO_INITFN_DEDUCED_RESULT_TYPE( \+        CompletionToken, Sig0, \+        (async_result<typename decay<CompletionToken>::type, \+          Sig0>::initiate( \+            declval<ASIO_MOVE_ARG(Initiation)>(), \+            declval<ASIO_MOVE_ARG(CompletionToken)>(), \+            ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \+  async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return async_result<typename decay<CompletionToken>::type, \+      Sig0>::initiate( \+        ASIO_MOVE_CAST(Initiation)(initiation), \+        ASIO_MOVE_CAST(CompletionToken)(token), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <typename CompletionToken, \+      ASIO_COMPLETION_SIGNATURE Sig0, \+      ASIO_COMPLETION_SIGNATURE Sig1, \+      typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+  inline typename constraint< \+      detail::async_result_has_initiate_memfn< \+        CompletionToken, Sig0, Sig1>::value, \+      ASIO_INITFN_DEDUCED_RESULT_TYPE2( \+        CompletionToken, Sig0, Sig1, \+        (async_result<typename decay<CompletionToken>::type, \+          Sig0, Sig1>::initiate( \+            declval<ASIO_MOVE_ARG(Initiation)>(), \+            declval<ASIO_MOVE_ARG(CompletionToken)>(), \+            ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \+  async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return async_result<typename decay<CompletionToken>::type, \+      Sig0, Sig1>::initiate( \+        ASIO_MOVE_CAST(Initiation)(initiation), \+        ASIO_MOVE_CAST(CompletionToken)(token), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <typename CompletionToken, \+      ASIO_COMPLETION_SIGNATURE Sig0, \+      ASIO_COMPLETION_SIGNATURE Sig1, \+      ASIO_COMPLETION_SIGNATURE Sig2, \+      typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+  inline typename constraint< \+      detail::async_result_has_initiate_memfn< \+        CompletionToken, Sig0, Sig1, Sig2>::value, \+      ASIO_INITFN_DEDUCED_RESULT_TYPE3( \+        CompletionToken, Sig0, Sig1, Sig2, \+        (async_result<typename decay<CompletionToken>::type, \+          Sig0, Sig1, Sig2>::initiate( \+            declval<ASIO_MOVE_ARG(Initiation)>(), \+            declval<ASIO_MOVE_ARG(CompletionToken)>(), \+            ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \+  async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return async_result<typename decay<CompletionToken>::type, \+      Sig0, Sig1, Sig2>::initiate( \+        ASIO_MOVE_CAST(Initiation)(initiation), \+        ASIO_MOVE_CAST(CompletionToken)(token), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <typename CompletionToken, \+      ASIO_COMPLETION_SIGNATURE Sig0, \+      typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+  inline typename constraint< \+      !detail::async_result_has_initiate_memfn< \+        CompletionToken, Sig0>::value, \+      ASIO_INITFN_RESULT_TYPE(CompletionToken, Sig0)>::type \+  async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    async_completion<CompletionToken, \+      Sig0> completion(token); \+  \+    ASIO_MOVE_CAST(Initiation)(initiation)( \+        ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, \+          Sig0))(completion.completion_handler), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  \+    return completion.result.get(); \+  } \+  \+  template <typename CompletionToken, \+      ASIO_COMPLETION_SIGNATURE Sig0, \+      ASIO_COMPLETION_SIGNATURE Sig1, \+      typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+  inline typename constraint< \+      !detail::async_result_has_initiate_memfn< \+        CompletionToken, Sig0, Sig1>::value, \+      ASIO_INITFN_RESULT_TYPE2(CompletionToken, Sig0, Sig1)>::type \+  async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    async_completion<CompletionToken, \+      Sig0, Sig1> completion(token); \+  \+    ASIO_MOVE_CAST(Initiation)(initiation)( \+        ASIO_MOVE_CAST(ASIO_HANDLER_TYPE2(CompletionToken, \+          Sig0, Sig1))(completion.completion_handler), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  \+    return completion.result.get(); \+  } \+  \+  template <typename CompletionToken, \+      ASIO_COMPLETION_SIGNATURE Sig0, \+      ASIO_COMPLETION_SIGNATURE Sig1, \+      ASIO_COMPLETION_SIGNATURE Sig2, \+      typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+  inline typename constraint< \+      !detail::async_result_has_initiate_memfn< \+        CompletionToken, Sig0, Sig1, Sig2>::value, \+      ASIO_INITFN_RESULT_TYPE3(CompletionToken, Sig0, Sig1, Sig2)>::type \+  async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    async_completion<CompletionToken, \+      Sig0, Sig1, Sig2> completion(token); \+  \+    ASIO_MOVE_CAST(Initiation)(initiation)( \+        ASIO_MOVE_CAST(ASIO_HANDLER_TYPE3(CompletionToken, \+          Sig0, Sig1, Sig2))(completion.completion_handler), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  \+    return completion.result.get(); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS) \+  && defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  && defined(ASIO_HAS_DECLTYPE)++namespace detail {++template <typename... Signatures>+struct initiation_archetype+{+  template <completion_handler_for<Signatures...> CompletionHandler>+  void operator()(CompletionHandler&&) const+  {+  }+};++} // namespace detail++template <typename T, typename... Signatures>+ASIO_CONCEPT completion_token_for =+  detail::are_completion_signatures<Signatures...>::value+  &&+  requires(T&& t)+  {+    async_initiate<T, Signatures...>(+        detail::initiation_archetype<Signatures...>{}, t);+  };++#define ASIO_COMPLETION_TOKEN_FOR(sig) \+  ::asio::completion_token_for<sig>+#define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) \+  ::asio::completion_token_for<sig0, sig1>+#define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) \+  ::asio::completion_token_for<sig0, sig1, sig2>++#else // defined(ASIO_HAS_CONCEPTS)+      //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)+      //   && defined(ASIO_HAS_DECLTYPE)++#define ASIO_COMPLETION_TOKEN_FOR(sig) typename+#define ASIO_COMPLETION_TOKEN_FOR2(sig0, sig1) typename+#define ASIO_COMPLETION_TOKEN_FOR3(sig0, sig1, sig2) typename++#endif // defined(ASIO_HAS_CONCEPTS)+       //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   && defined(ASIO_HAS_DECLTYPE)++namespace detail {++struct async_operation_probe {};+struct async_operation_probe_result {};++template <typename Call, typename = void>+struct is_async_operation_call : false_type+{+};++template <typename Call>+struct is_async_operation_call<Call,+    typename void_type<+      typename enable_if<+        is_same<+          typename result_of<Call>::type,+          async_operation_probe_result+        >::value+      >::type+    >::type> : true_type+{+};++} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... Signatures>+class async_result<detail::async_operation_probe, Signatures...>+{+public:+  typedef detail::async_operation_probe_result return_type;++  template <typename Initiation, typename... InitArgs>+  static return_type initiate(ASIO_MOVE_ARG(Initiation),+      detail::async_operation_probe, ASIO_MOVE_ARG(InitArgs)...)+  {+    return return_type();+  }+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++namespace detail {++struct async_result_probe_base+{+  typedef detail::async_operation_probe_result return_type;++  template <typename Initiation>+  static return_type initiate(ASIO_MOVE_ARG(Initiation),+      detail::async_operation_probe)+  {+    return return_type();+  }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+  static return_type initiate(ASIO_MOVE_ARG(Initiation), \+      detail::async_operation_probe, \+      ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n)) \+  { \+    return return_type(); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF+};++} // namespace detail++template <typename Sig0>+class async_result<detail::async_operation_probe, Sig0>+  : public detail::async_result_probe_base {};++template <typename Sig0, typename Sig1>+class async_result<detail::async_operation_probe, Sig0, Sig1>+  : public detail::async_result_probe_base {};++template <typename Sig0, typename Sig1, typename Sig2>+class async_result<detail::async_operation_probe, Sig0, Sig1, Sig2>+  : public detail::async_result_probe_base {};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(GENERATING_DOCUMENTATION)++#if defined(GENERATING_DOCUMENTATION)++/// The is_async_operation trait detects whether a type @c T and arguments+/// @c Args... may be used to initiate an asynchronous operation.+/**+ * Class template @c is_async_operation is a trait is derived from @c true_type+ * if the expression <tt>T(Args..., token)</tt> initiates an asynchronous+ * operation, where @c token is an unspecified completion token type. Otherwise,+ * @c is_async_operation is derived from @c false_type.+ */+template <typename T, typename... Args>+struct is_async_operation : integral_constant<bool, automatically_determined>+{+};++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Args>+struct is_async_operation :+  detail::is_async_operation_call<+    T(Args..., detail::async_operation_probe)>+{+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void, typename = void,+    typename = void, typename = void>+struct is_async_operation;++template <typename T>+struct is_async_operation<T> :+  detail::is_async_operation_call<+    T(detail::async_operation_probe)>+{+};++#define ASIO_PRIVATE_IS_ASYNC_OP_DEF(n) \+  template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+  struct is_async_operation<T, ASIO_VARIADIC_TARGS(n)> : \+    detail::is_async_operation_call< \+      T(ASIO_VARIADIC_TARGS(n), detail::async_operation_probe)> \+  { \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_IS_ASYNC_OP_DEF)+#undef ASIO_PRIVATE_IS_ASYNC_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS) \+  && defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Args>+ASIO_CONCEPT async_operation = is_async_operation<T, Args...>::value;++#define ASIO_ASYNC_OPERATION(t) \+  ::asio::async_operation<t>+#define ASIO_ASYNC_OPERATION1(t, a0) \+  ::asio::async_operation<t, a0>+#define ASIO_ASYNC_OPERATION2(t, a0, a1) \+  ::asio::async_operation<t, a0, a1>+#define ASIO_ASYNC_OPERATION3(t, a0, a1, a2) \+  ::asio::async_operation<t, a0, a1, a2>++#else // defined(ASIO_HAS_CONCEPTS)+      //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_ASYNC_OPERATION(t) typename+#define ASIO_ASYNC_OPERATION1(t, a0) typename+#define ASIO_ASYNC_OPERATION2(t, a0, a1) typename+#define ASIO_ASYNC_OPERATION3(t, a0, a1, a2) typename++#endif // defined(ASIO_HAS_CONCEPTS)+       //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)++namespace detail {++struct completion_signature_probe {};++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... T>+struct completion_signature_probe_result+{+  template <template <typename...> class Op>+  struct apply+  {+    typedef Op<T...> type;+  };+};++template <typename T>+struct completion_signature_probe_result<T>+{+  typedef T type;++  template <template <typename...> class Op>+  struct apply+  {+    typedef Op<T> type;+  };+};++template <>+struct completion_signature_probe_result<void>+{+  template <template <typename...> class Op>+  struct apply+  {+    typedef Op<> type;+  };+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct completion_signature_probe_result+{+  typedef T type;+};++template <>+struct completion_signature_probe_result<void>+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... Signatures>+class async_result<detail::completion_signature_probe, Signatures...>+{+public:+  typedef detail::completion_signature_probe_result<Signatures...> return_type;++  template <typename Initiation, typename... InitArgs>+  static return_type initiate(ASIO_MOVE_ARG(Initiation),+      detail::completion_signature_probe, ASIO_MOVE_ARG(InitArgs)...)+  {+    return return_type();+  }+};++template <typename Signature>+class async_result<detail::completion_signature_probe, Signature>+{+public:+  typedef detail::completion_signature_probe_result<Signature> return_type;++  template <typename Initiation, typename... InitArgs>+  static return_type initiate(ASIO_MOVE_ARG(Initiation),+      detail::completion_signature_probe, ASIO_MOVE_ARG(InitArgs)...)+  {+    return return_type();+  }+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++namespace detail {++template <typename Signature>+class async_result_sig_probe_base+{+public:+  typedef detail::completion_signature_probe_result<Signature> return_type;++  template <typename Initiation>+  static return_type initiate(ASIO_MOVE_ARG(Initiation),+      detail::async_operation_probe)+  {+    return return_type();+  }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+  static return_type initiate(ASIO_MOVE_ARG(Initiation), \+      detail::completion_signature_probe, \+      ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n)) \+  { \+    return return_type(); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF+};++} // namespace detail++template <>+class async_result<detail::completion_signature_probe>+  : public detail::async_result_sig_probe_base<void> {};++template <typename Sig0>+class async_result<detail::completion_signature_probe, Sig0>+  : public detail::async_result_sig_probe_base<Sig0> {};++template <typename Sig0, typename Sig1>+class async_result<detail::completion_signature_probe, Sig0, Sig1>+  : public detail::async_result_sig_probe_base<void> {};++template <typename Sig0, typename Sig1, typename Sig2>+class async_result<detail::completion_signature_probe, Sig0, Sig1, Sig2>+  : public detail::async_result_sig_probe_base<void> {};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(GENERATING_DOCUMENTATION)++#if defined(GENERATING_DOCUMENTATION)++/// The completion_signature_of trait determines the completion signature+/// of an asynchronous operation.+/**+ * Class template @c completion_signature_of is a trait with a member type+ * alias @c type that denotes the completion signature of the asynchronous+ * operation initiated by the expression <tt>T(Args..., token)</tt> operation,+ * where @c token is an unspecified completion token type. If the asynchronous+ * operation does not have exactly one completion signature, the instantion of+ * the trait is well-formed but the member type alias @c type is omitted. If+ * the expression <tt>T(Args..., token)</tt> is not an asynchronous operation+ * then use of the trait is ill-formed.+ */+template <typename T, typename... Args>+struct completion_signature_of+{+  typedef automatically_determined type;+};++template <typename T, typename... Args>+using completion_signature_of_t =+  typename completion_signature_of<T, Args...>::type;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Args>+struct completion_signature_of :+  result_of<T(Args..., detail::completion_signature_probe)>::type+{+};++#if defined(ASIO_HAS_ALIAS_TEMPLATES)+template <typename T, typename... Args>+using completion_signature_of_t =+  typename completion_signature_of<T, Args...>::type;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void, typename = void,+    typename = void, typename = void>+struct completion_signature_of;++template <typename T>+struct completion_signature_of<T> :+  result_of<T(detail::completion_signature_probe)>::type+{+};++#define ASIO_PRIVATE_COMPLETION_SIG_OF_DEF(n) \+  template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+  struct completion_signature_of<T, ASIO_VARIADIC_TARGS(n)> : \+    result_of< \+      T(ASIO_VARIADIC_TARGS(n), \+        detail::completion_signature_probe)>::type \+  { \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPLETION_SIG_OF_DEF)+#undef ASIO_PRIVATE_COMPLETION_SIG_OF_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++namespace detail {++template <typename T, typename = void>+struct default_completion_token_impl+{+  typedef void type;+};++template <typename T>+struct default_completion_token_impl<T,+  typename void_type<typename T::default_completion_token_type>::type>+{+  typedef typename T::default_completion_token_type type;+};++} // namespace detail++#if defined(GENERATING_DOCUMENTATION)++/// Traits type used to determine the default completion token type associated+/// with a type (such as an executor).+/**+ * A program may specialise this traits type if the @c T template parameter in+ * the specialisation is a user-defined type.+ *+ * Specialisations of this trait may provide a nested typedef @c type, which is+ * a default-constructible completion token type.+ */+template <typename T>+struct default_completion_token+{+  /// If @c T has a nested type @c default_completion_token_type,+  /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type+  /// is not defined.+  typedef see_below type;+};+#else+template <typename T>+struct default_completion_token+  : detail::default_completion_token_impl<T>+{+};+#endif++#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename T>+using default_completion_token_t = typename default_completion_token<T>::type;++#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)++#if defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)++#define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \+  = typename ::asio::default_completion_token<e>::type+#define ASIO_DEFAULT_COMPLETION_TOKEN(e) \+  = typename ::asio::default_completion_token<e>::type()++#else // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)++#define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e)+#define ASIO_DEFAULT_COMPLETION_TOKEN(e)++#endif // defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)++} // namespace asio++#include "asio/detail/pop_options.hpp"  #endif // ASIO_ASYNC_RESULT_HPP
link/modules/asio-standalone/asio/include/asio/awaitable.hpp view
@@ -2,7 +2,7 @@ // awaitable.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -136,9 +136,6 @@ #include "asio/detail/pop_options.hpp"  #include "asio/impl/awaitable.hpp"-#if defined(ASIO_HEADER_ONLY)-# include "asio/impl/awaitable.ipp"-#endif // defined(ASIO_HEADER_ONLY)  #endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) 
link/modules/asio-standalone/asio/include/asio/basic_datagram_socket.hpp view
@@ -2,7 +2,7 @@ // basic_datagram_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -113,9 +113,9 @@    */   template <typename ExecutionContext>   explicit basic_datagram_socket(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context)   {   }@@ -151,10 +151,10 @@   template <typename ExecutionContext>   basic_datagram_socket(ExecutionContext& context,       const protocol_type& protocol,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_socket<Protocol, Executor>(context, protocol)   {   }@@ -198,9 +198,9 @@   template <typename ExecutionContext>   basic_datagram_socket(ExecutionContext& context,       const endpoint_type& endpoint,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context, endpoint)   {   }@@ -243,13 +243,14 @@   template <typename ExecutionContext>   basic_datagram_socket(ExecutionContext& context,       const protocol_type& protocol, const native_handle_type& native_socket,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context, protocol, native_socket)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_datagram_socket from another.   /**    * This constructor moves a datagram socket from one object to another.@@ -261,7 +262,7 @@    * constructed using the @c basic_datagram_socket(const executor_type&)    * constructor.    */-  basic_datagram_socket(basic_datagram_socket&& other) noexcept+  basic_datagram_socket(basic_datagram_socket&& other) ASIO_NOEXCEPT     : basic_socket<Protocol, Executor>(std::move(other))   {   }@@ -298,10 +299,10 @@    */   template <typename Protocol1, typename Executor1>   basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Protocol1, Protocol>::value           && is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(std::move(other))   {   }@@ -320,15 +321,16 @@    * constructor.    */   template <typename Protocol1, typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Protocol1, Protocol>::value       && is_convertible<Executor1, Executor>::value,     basic_datagram_socket&-  > operator=(basic_datagram_socket<Protocol1, Executor1>&& other)+  >::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)   {     basic_socket<Protocol, Executor>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the socket.   /**@@ -345,7 +347,7 @@    * call will block until the data has been sent successfully or an error    * occurs.    *-   * @param buffers One or more data buffers to be sent on the socket.+   * @param buffers One ore more data buffers to be sent on the socket.    *    * @returns The number of bytes sent.    *@@ -377,7 +379,7 @@    * call will block until the data has been sent successfully or an error    * occurs.    *-   * @param buffers One or more data buffers to be sent on the socket.+   * @param buffers One ore more data buffers to be sent on the socket.    *    * @param flags Flags specifying how the send call is to be made.    *@@ -447,7 +449,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -477,14 +479,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_send>(), token,-          buffers, socket_base::message_flags(0)))+          buffers, socket_base::message_flags(0))))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -517,7 +523,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -538,14 +544,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send(const ConstBufferSequence& buffers,+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send(const ConstBufferSequence& buffers,       socket_base::message_flags flags,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_send>(), token, buffers, flags))+          declval<initiate_async_send>(), token, buffers, flags)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -666,7 +676,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -695,15 +705,19 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send_to(const ConstBufferSequence& buffers,+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send_to(const ConstBufferSequence& buffers,       const endpoint_type& destination,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_send_to>(), token, buffers,-          destination, socket_base::message_flags(0)))+          destination, socket_base::message_flags(0))))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -739,7 +753,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -756,15 +770,19 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send_to(const ConstBufferSequence& buffers,+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send_to(const ConstBufferSequence& buffers,       const endpoint_type& destination, socket_base::message_flags flags,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_send_to>(), token,-          buffers, destination, flags))+          buffers, destination, flags)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -884,7 +902,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -915,14 +933,18 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive>(), token,-          buffers, socket_base::message_flags(0)))+          buffers, socket_base::message_flags(0))))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -955,7 +977,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -976,14 +998,18 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive(const MutableBufferSequence& buffers,+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive(const MutableBufferSequence& buffers,       socket_base::message_flags flags,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_receive>(), token, buffers, flags))+          declval<initiate_async_receive>(), token, buffers, flags)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -1026,7 +1052,7 @@     asio::detail::throw_error(ec, "receive_from");     return s;   }-+     /// Receive a datagram with the endpoint of the sender.   /**    * This function is used to receive a datagram. The function call will block@@ -1053,7 +1079,7 @@     asio::detail::throw_error(ec, "receive_from");     return s;   }-+     /// Receive a datagram with the endpoint of the sender.   /**    * This function is used to receive a datagram. The function call will block@@ -1107,7 +1133,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -1133,15 +1159,19 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive_from(const MutableBufferSequence& buffers,+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive_from(const MutableBufferSequence& buffers,       endpoint_type& sender_endpoint,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive_from>(), token, buffers,-          &sender_endpoint, socket_base::message_flags(0)))+          &sender_endpoint, socket_base::message_flags(0))))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -1179,7 +1209,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -1196,15 +1226,19 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive_from(const MutableBufferSequence& buffers,+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive_from(const MutableBufferSequence& buffers,       endpoint_type& sender_endpoint, socket_base::message_flags flags,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive_from>(), token,-          buffers, &sender_endpoint, flags))+          buffers, &sender_endpoint, flags)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -1214,12 +1248,12 @@  private:   // Disallow copying and assignment.-  basic_datagram_socket(const basic_datagram_socket&) = delete;+  basic_datagram_socket(const basic_datagram_socket&) ASIO_DELETED;   basic_datagram_socket& operator=(-      const basic_datagram_socket&) = delete;+      const basic_datagram_socket&) ASIO_DELETED;    class initiate_async_send-  {+  {    public:     typedef Executor executor_type; @@ -1228,13 +1262,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers,         socket_base::message_flags flags) const     {@@ -1262,13 +1296,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers, const endpoint_type& destination,         socket_base::message_flags flags) const     {@@ -1296,13 +1330,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers,         socket_base::message_flags flags) const     {@@ -1330,13 +1364,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers, endpoint_type* sender_endpoint,         socket_base::message_flags flags) const     {
link/modules/asio-standalone/asio/include/asio/basic_deadline_timer.hpp view
@@ -2,7 +2,7 @@ // basic_deadline_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,8 +17,6 @@  #include "asio/detail/config.hpp" -#if !defined(ASIO_NO_DEPRECATED)- #if defined(ASIO_HAS_BOOST_DATE_TIME) \   || defined(GENERATING_DOCUMENTATION) @@ -37,8 +35,7 @@  namespace asio { -/// (Deprecated: Use basic_waitable_timer.) Provides waitable timer-/// functionality.+/// Provides waitable timer functionality. /**  * The basic_deadline_timer class template provides the ability to perform a  * blocking or asynchronous wait for a timer to expire.@@ -66,7 +63,7 @@  * timer.wait();  * @endcode  *- * @par+ * @par   * Performing an asynchronous wait:  * @code  * void handler(const asio::error_code& error)@@ -181,9 +178,9 @@    */   template <typename ExecutionContext>   explicit basic_deadline_timer(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {   }@@ -219,9 +216,9 @@    */   template <typename ExecutionContext>   basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -263,9 +260,9 @@   template <typename ExecutionContext>   basic_deadline_timer(ExecutionContext& context,       const duration_type& expiry_time,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -274,6 +271,7 @@     asio::detail::throw_error(ec, "expires_from_now");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_deadline_timer from another.   /**    * This constructor moves a timer from one object to another.@@ -307,6 +305,7 @@     impl_ = std::move(other.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the timer.   /**@@ -318,7 +317,7 @@   }    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -633,7 +632,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -650,12 +649,15 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        WaitToken = default_completion_token_t<executor_type>>-  auto async_wait(-      WaitToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+      void (asio::error_code))+  async_wait(+      ASIO_MOVE_ARG(WaitToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WaitToken, void (asio::error_code)>(-        declval<initiate_async_wait>(), token))+          declval<initiate_async_wait>(), token)))   {     return async_initiate<WaitToken, void (asio::error_code)>(         initiate_async_wait(this), token);@@ -663,9 +665,9 @@  private:   // Disallow copying and assignment.-  basic_deadline_timer(const basic_deadline_timer&) = delete;+  basic_deadline_timer(const basic_deadline_timer&) ASIO_DELETED;   basic_deadline_timer& operator=(-      const basic_deadline_timer&) = delete;+      const basic_deadline_timer&) ASIO_DELETED;    class initiate_async_wait   {@@ -677,13 +679,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WaitHandler>-    void operator()(WaitHandler&& handler) const+    void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WaitHandler.@@ -709,7 +711,5 @@  #endif // defined(ASIO_HAS_BOOST_DATE_TIME)        // || defined(GENERATING_DOCUMENTATION)--#endif // !defined(ASIO_NO_DEPRECATED)  #endif // ASIO_BASIC_DEADLINE_TIMER_HPP
link/modules/asio-standalone/asio/include/asio/basic_file.hpp view
@@ -2,7 +2,7 @@ // basic_file.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,7 +21,6 @@   || defined(GENERATING_DOCUMENTATION)  #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/cstdint.hpp"@@ -40,6 +39,10 @@ # include "asio/detail/io_uring_file_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -109,10 +112,10 @@    */   template <typename ExecutionContext>   explicit basic_file(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {   }@@ -128,20 +131,6 @@    *    * @param open_flags A set of flags that determine how the file should be    * opened.-   *-   * Exactly one of the following file_base::flags values must be specified:-   *-   * @li flags::read_only-   * @li flags::write_only-   * @li flags::read_write-   *-   * The following flags may be bitwise or-ed in addition:-   *-   * @li flags::append-   * @li flags::create-   * @li flags::exclusive-   * @li flags::truncate-   * @li flags::sync_all_on_write    */   explicit basic_file(const executor_type& ex,       const char* path, file_base::flags open_flags)@@ -152,7 +141,7 @@     asio::detail::throw_error(ec, "open");   } -  /// Construct and open a basic_file.+  /// Construct a basic_file without opening it.   /**    * This constructor initialises a file and opens it.    *@@ -164,28 +153,14 @@    *    * @param open_flags A set of flags that determine how the file should be    * opened.-   *-   * Exactly one of the following file_base::flags values must be specified:-   *-   * @li flags::read_only-   * @li flags::write_only-   * @li flags::read_write-   *-   * The following flags may be bitwise or-ed in addition:-   *-   * @li flags::append-   * @li flags::create-   * @li flags::exclusive-   * @li flags::truncate-   * @li flags::sync_all_on_write    */   template <typename ExecutionContext>   explicit basic_file(ExecutionContext& context,       const char* path, file_base::flags open_flags,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {     asio::error_code ec;@@ -204,20 +179,6 @@    *    * @param open_flags A set of flags that determine how the file should be    * opened.-   *-   * Exactly one of the following file_base::flags values must be specified:-   *-   * @li flags::read_only-   * @li flags::write_only-   * @li flags::read_write-   *-   * The following flags may be bitwise or-ed in addition:-   *-   * @li flags::append-   * @li flags::create-   * @li flags::exclusive-   * @li flags::truncate-   * @li flags::sync_all_on_write    */   explicit basic_file(const executor_type& ex,       const std::string& path, file_base::flags open_flags)@@ -229,7 +190,7 @@     asio::detail::throw_error(ec, "open");   } -  /// Construct and open a basic_file.+  /// Construct a basic_file without opening it.   /**    * This constructor initialises a file and opens it.    *@@ -241,28 +202,14 @@    *    * @param open_flags A set of flags that determine how the file should be    * opened.-   *-   * Exactly one of the following file_base::flags values must be specified:-   *-   * @li flags::read_only-   * @li flags::write_only-   * @li flags::read_write-   *-   * The following flags may be bitwise or-ed in addition:-   *-   * @li flags::append-   * @li flags::create-   * @li flags::exclusive-   * @li flags::truncate-   * @li flags::sync_all_on_write    */   template <typename ExecutionContext>   explicit basic_file(ExecutionContext& context,       const std::string& path, file_base::flags open_flags,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {     asio::error_code ec;@@ -305,10 +252,10 @@    */   template <typename ExecutionContext>   basic_file(ExecutionContext& context, const native_handle_type& native_file,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {     asio::error_code ec;@@ -317,6 +264,7 @@     asio::detail::throw_error(ec, "assign");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_file from another.   /**    * This constructor moves a file from one object to another.@@ -327,7 +275,7 @@    * @note Following the move, the moved-from object is in the same state as if    * constructed using the @c basic_file(const executor_type&) constructor.    */-  basic_file(basic_file&& other) noexcept+  basic_file(basic_file&& other) ASIO_NOEXCEPT     : impl_(std::move(other.impl_))   {   }@@ -364,10 +312,10 @@    */   template <typename Executor1>   basic_file(basic_file<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(std::move(other.impl_))   {   }@@ -383,18 +331,19 @@    * constructed using the @c basic_file(const executor_type&) constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_file&-  > operator=(basic_file<Executor1>&& other)+  >::type operator=(basic_file<Executor1>&& other)   {     basic_file tmp(std::move(other));     impl_ = std::move(tmp.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -410,20 +359,6 @@    *    * @throws asio::system_error Thrown on failure.    *-   * Exactly one of the following file_base::flags values must be specified:-   *-   * @li flags::read_only-   * @li flags::write_only-   * @li flags::read_write-   *-   * The following flags may be bitwise or-ed in addition:-   *-   * @li flags::append-   * @li flags::create-   * @li flags::exclusive-   * @li flags::truncate-   * @li flags::sync_all_on_write-   *    * @par Example    * @code    * asio::stream_file file(my_context);@@ -446,20 +381,6 @@    * @param open_flags A set of flags that determine how the file should be    * opened.    *-   * Exactly one of the following file_base::flags values must be specified:-   *-   * @li flags::read_only-   * @li flags::write_only-   * @li flags::read_write-   *-   * The following flags may be bitwise or-ed in addition:-   *-   * @li flags::append-   * @li flags::create-   * @li flags::exclusive-   * @li flags::truncate-   * @li flags::sync_all_on_write-   *    * @param ec Set to indicate what error occurred, if any.    *    * @par Example@@ -491,20 +412,6 @@    *    * @throws asio::system_error Thrown on failure.    *-   * Exactly one of the following file_base::flags values must be specified:-   *-   * @li flags::read_only-   * @li flags::write_only-   * @li flags::read_write-   *-   * The following flags may be bitwise or-ed in addition:-   *-   * @li flags::append-   * @li flags::create-   * @li flags::exclusive-   * @li flags::truncate-   * @li flags::sync_all_on_write-   *    * @par Example    * @code    * asio::stream_file file(my_context);@@ -530,20 +437,6 @@    *    * @param ec Set to indicate what error occurred, if any.    *-   * Exactly one of the following file_base::flags values must be specified:-   *-   * @li flags::read_only-   * @li flags::write_only-   * @li flags::read_write-   *-   * The following flags may be bitwise or-ed in addition:-   *-   * @li flags::append-   * @li flags::create-   * @li flags::exclusive-   * @li flags::truncate-   * @li flags::sync_all_on_write-   *    * @par Example    * @code    * asio::stream_file file(my_context);@@ -922,8 +815,8 @@  private:   // Disallow copying and assignment.-  basic_file(const basic_file&) = delete;-  basic_file& operator=(const basic_file&) = delete;+  basic_file(const basic_file&) ASIO_DELETED;+  basic_file& operator=(const basic_file&) ASIO_DELETED; };  } // namespace asio
link/modules/asio-standalone/asio/include/asio/basic_io_object.hpp view
@@ -2,7 +2,7 @@ // basic_io_object.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,16 +16,13 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"--#if !defined(ASIO_NO_DEPRECATED) \-  || defined(GENERATING_DOCUMENTATION)- #include "asio/io_context.hpp"  #include "asio/detail/push_options.hpp"  namespace asio { +#if defined(ASIO_HAS_MOVE) namespace detail {   // Type trait used to determine whether a service supports move.@@ -48,13 +45,14 @@         static_cast<implementation_type*>(0))) == 1;   }; }+#endif // defined(ASIO_HAS_MOVE) -/// (Deprecated) Base class for all I/O objects.+/// Base class for all I/O objects. /**  * @note All I/O objects are non-copyable. However, when using C++0x, certain  * I/O objects do support move construction and move assignment.  */-#if defined(GENERATING_DOCUMENTATION)+#if !defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) template <typename IoObjectService> #else template <typename IoObjectService,@@ -69,7 +67,9 @@   /// The underlying implementation type of I/O object.   typedef typename service_type::implementation_type implementation_type; -  /// Get the io_context associated with the object.+#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use get_executor().) Get the io_context associated with the+  /// object.   /**    * This function may be used to obtain the io_context object that the I/O    * object uses to dispatch handlers for asynchronous operations.@@ -82,7 +82,8 @@     return service_.get_io_context();   } -  /// Get the io_context associated with the object.+  /// (Deprecated: Use get_executor().) Get the io_context associated with the+  /// object.   /**    * This function may be used to obtain the io_context object that the I/O    * object uses to dispatch handlers for asynchronous operations.@@ -94,12 +95,13 @@   {     return service_.get_io_context();   }+#endif // !defined(ASIO_NO_DEPRECATED)    /// The type of the executor associated with the object.   typedef asio::io_context::executor_type executor_type;    /// Get the executor associated with the object.-  executor_type get_executor() noexcept+  executor_type get_executor() ASIO_NOEXCEPT   {     return service_.get_io_context().get_executor();   }@@ -188,6 +190,7 @@   implementation_type implementation_; }; +#if defined(ASIO_HAS_MOVE) // Specialisation for movable objects. template <typename IoObjectService> class basic_io_object<IoObjectService, true>@@ -196,6 +199,7 @@   typedef IoObjectService service_type;   typedef typename service_type::implementation_type implementation_type; +#if !defined(ASIO_NO_DEPRECATED)   asio::io_context& get_io_context()   {     return service_->get_io_context();@@ -205,10 +209,11 @@   {     return service_->get_io_context();   }+#endif // !defined(ASIO_NO_DEPRECATED)    typedef asio::io_context::executor_type executor_type; -  executor_type get_executor() noexcept+  executor_type get_executor() ASIO_NOEXCEPT   {     return service_->get_io_context().get_executor();   }@@ -276,12 +281,10 @@   IoObjectService* service_;   implementation_type implementation_; };+#endif // defined(ASIO_HAS_MOVE)  } // namespace asio  #include "asio/detail/pop_options.hpp"--#endif // !defined(ASIO_NO_DEPRECATED)-       //   || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_BASIC_IO_OBJECT_HPP
link/modules/asio-standalone/asio/include/asio/basic_random_access_file.hpp view
@@ -2,7 +2,7 @@ // basic_random_access_file.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -107,10 +107,10 @@    */   template <typename ExecutionContext>   explicit basic_random_access_file(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(context)   {   }@@ -153,10 +153,10 @@   template <typename ExecutionContext>   basic_random_access_file(ExecutionContext& context,       const char* path, file_base::flags open_flags,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(context, path, open_flags)   {   }@@ -199,10 +199,10 @@   template <typename ExecutionContext>   basic_random_access_file(ExecutionContext& context,       const std::string& path, file_base::flags open_flags,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(context, path, open_flags)   {   }@@ -241,14 +241,15 @@   template <typename ExecutionContext>   basic_random_access_file(ExecutionContext& context,       const native_handle_type& native_file,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(context, native_file)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_random_access_file from another.   /**    * This constructor moves a random-access file from one object to another.@@ -260,7 +261,7 @@    * constructed using the @c basic_random_access_file(const executor_type&)    * constructor.    */-  basic_random_access_file(basic_random_access_file&& other) noexcept+  basic_random_access_file(basic_random_access_file&& other) ASIO_NOEXCEPT     : basic_file<Executor>(std::move(other))   {   }@@ -297,10 +298,10 @@    */   template <typename Executor1>   basic_random_access_file(basic_random_access_file<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(std::move(other))   {   }@@ -319,14 +320,15 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_random_access_file&-  > operator=(basic_random_access_file<Executor1>&& other)+  >::type operator=(basic_random_access_file<Executor1>&& other)   {     basic_file<Executor>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the file.   /**@@ -427,7 +429,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -457,13 +459,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_write_some_at(uint64_t offset, const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_write_some_at(uint64_t offset,+      const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_write_some_at>(), token, offset, buffers))+          declval<initiate_async_write_some_at>(), token, offset, buffers)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -562,7 +569,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -593,13 +600,18 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_read_some_at(uint64_t offset, const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_read_some_at(uint64_t offset,+      const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_read_some_at>(), token, offset, buffers))+          declval<initiate_async_read_some_at>(), token, offset, buffers)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -608,9 +620,9 @@  private:   // Disallow copying and assignment.-  basic_random_access_file(const basic_random_access_file&) = delete;+  basic_random_access_file(const basic_random_access_file&) ASIO_DELETED;   basic_random_access_file& operator=(-      const basic_random_access_file&) = delete;+      const basic_random_access_file&) ASIO_DELETED;    class initiate_async_write_some_at   {@@ -622,13 +634,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         uint64_t offset, const ConstBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler@@ -655,13 +667,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         uint64_t offset, const MutableBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_raw_socket.hpp view
@@ -2,7 +2,7 @@ // basic_raw_socket.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -113,9 +113,9 @@    */   template <typename ExecutionContext>   explicit basic_raw_socket(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context)   {   }@@ -150,10 +150,10 @@    */   template <typename ExecutionContext>   basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_socket<Protocol, Executor>(context, protocol)   {   }@@ -196,9 +196,9 @@    */   template <typename ExecutionContext>   basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context, endpoint)   {   }@@ -241,13 +241,14 @@   template <typename ExecutionContext>   basic_raw_socket(ExecutionContext& context,       const protocol_type& protocol, const native_handle_type& native_socket,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context, protocol, native_socket)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_raw_socket from another.   /**    * This constructor moves a raw socket from one object to another.@@ -259,7 +260,7 @@    * constructed using the @c basic_raw_socket(const executor_type&)    * constructor.    */-  basic_raw_socket(basic_raw_socket&& other) noexcept+  basic_raw_socket(basic_raw_socket&& other) ASIO_NOEXCEPT     : basic_socket<Protocol, Executor>(std::move(other))   {   }@@ -295,10 +296,10 @@    */   template <typename Protocol1, typename Executor1>   basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Protocol1, Protocol>::value           && is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(std::move(other))   {   }@@ -315,15 +316,16 @@    * constructor.    */   template <typename Protocol1, typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Protocol1, Protocol>::value       && is_convertible<Executor1, Executor>::value,     basic_raw_socket&-  > operator=(basic_raw_socket<Protocol1, Executor1>&& other)+  >::type operator=(basic_raw_socket<Protocol1, Executor1>&& other)   {     basic_socket<Protocol, Executor>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the socket.   /**@@ -339,7 +341,7 @@    * This function is used to send data on the raw socket. The function call    * will block until the data has been sent successfully or an error occurs.    *-   * @param buffers One or more data buffers to be sent on the socket.+   * @param buffers One ore more data buffers to be sent on the socket.    *    * @returns The number of bytes sent.    *@@ -370,7 +372,7 @@    * This function is used to send data on the raw socket. The function call    * will block until the data has been sent successfully or an error occurs.    *-   * @param buffers One or more data buffers to be sent on the socket.+   * @param buffers One ore more data buffers to be sent on the socket.    *    * @param flags Flags specifying how the send call is to be made.    *@@ -439,7 +441,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -469,14 +471,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_send>(), token,-          buffers, socket_base::message_flags(0)))+          buffers, socket_base::message_flags(0))))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -509,7 +515,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -530,14 +536,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send(const ConstBufferSequence& buffers,+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send(const ConstBufferSequence& buffers,       socket_base::message_flags flags,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_send>(), token, buffers, flags))+          declval<initiate_async_send>(), token, buffers, flags)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -658,7 +668,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -687,15 +697,19 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send_to(const ConstBufferSequence& buffers,+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send_to(const ConstBufferSequence& buffers,       const endpoint_type& destination,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_send_to>(), token, buffers,-          destination, socket_base::message_flags(0)))+          destination, socket_base::message_flags(0))))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -731,7 +745,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -748,15 +762,19 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send_to(const ConstBufferSequence& buffers,+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send_to(const ConstBufferSequence& buffers,       const endpoint_type& destination, socket_base::message_flags flags,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_send_to>(), token,-          buffers, destination, flags))+          buffers, destination, flags)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -876,7 +894,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -907,14 +925,18 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive>(), token,-          buffers, socket_base::message_flags(0)))+          buffers, socket_base::message_flags(0))))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -947,7 +969,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -969,14 +991,17 @@   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         std::size_t)) ReadToken-          = default_completion_token_t<executor_type>>-  auto async_receive(const MutableBufferSequence& buffers,+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive(const MutableBufferSequence& buffers,       socket_base::message_flags flags,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_receive>(), token, buffers, flags))+          declval<initiate_async_receive>(), token, buffers, flags)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -1019,7 +1044,7 @@     asio::detail::throw_error(ec, "receive_from");     return s;   }-+     /// Receive raw data with the endpoint of the sender.   /**    * This function is used to receive raw data. The function call will block@@ -1046,7 +1071,7 @@     asio::detail::throw_error(ec, "receive_from");     return s;   }-+     /// Receive raw data with the endpoint of the sender.   /**    * This function is used to receive raw data. The function call will block@@ -1100,7 +1125,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -1126,16 +1151,19 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive_from(const MutableBufferSequence& buffers,+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive_from(const MutableBufferSequence& buffers,       endpoint_type& sender_endpoint,-      ReadToken&& token-        = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive_from>(), token, buffers,-          &sender_endpoint, socket_base::message_flags(0)))+          &sender_endpoint, socket_base::message_flags(0))))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -1173,7 +1201,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -1191,15 +1219,18 @@   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         std::size_t)) ReadToken-          = default_completion_token_t<executor_type>>-  auto async_receive_from(const MutableBufferSequence& buffers,+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive_from(const MutableBufferSequence& buffers,       endpoint_type& sender_endpoint, socket_base::message_flags flags,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive_from>(), token,-          buffers, &sender_endpoint, flags))+          buffers, &sender_endpoint, flags)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -1209,8 +1240,8 @@  private:   // Disallow copying and assignment.-  basic_raw_socket(const basic_raw_socket&) = delete;-  basic_raw_socket& operator=(const basic_raw_socket&) = delete;+  basic_raw_socket(const basic_raw_socket&) ASIO_DELETED;+  basic_raw_socket& operator=(const basic_raw_socket&) ASIO_DELETED;    class initiate_async_send   {@@ -1222,13 +1253,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers,         socket_base::message_flags flags) const     {@@ -1256,13 +1287,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers, const endpoint_type& destination,         socket_base::message_flags flags) const     {@@ -1290,13 +1321,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers,         socket_base::message_flags flags) const     {@@ -1324,13 +1355,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers, endpoint_type* sender_endpoint,         socket_base::message_flags flags) const     {
link/modules/asio-standalone/asio/include/asio/basic_readable_pipe.hpp view
@@ -2,7 +2,7 @@ // basic_readable_pipe.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,7 +21,6 @@   || defined(GENERATING_DOCUMENTATION)  #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -39,6 +38,10 @@ # include "asio/detail/reactive_descriptor_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -109,10 +112,10 @@    */   template <typename ExecutionContext>   explicit basic_readable_pipe(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {   }@@ -156,9 +159,9 @@   template <typename ExecutionContext>   basic_readable_pipe(ExecutionContext& context,       const native_handle_type& native_pipe,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -167,6 +170,7 @@     asio::detail::throw_error(ec, "assign");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_readable_pipe from another.   /**    * This constructor moves a pipe from one object to another.@@ -217,10 +221,10 @@    */   template <typename Executor1>   basic_readable_pipe(basic_readable_pipe<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(std::move(other.impl_))   {   }@@ -237,15 +241,16 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_readable_pipe&-  > operator=(basic_readable_pipe<Executor1>&& other)+  >::type operator=(basic_readable_pipe<Executor1>&& other)   {     basic_readable_pipe tmp(std::move(other));     impl_ = std::move(tmp.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the pipe.   /**@@ -258,7 +263,7 @@   }    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -534,7 +539,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -556,13 +561,17 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_read_some>(), token, buffers))+          declval<initiate_async_read_some>(), token, buffers)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -571,8 +580,8 @@  private:   // Disallow copying and assignment.-  basic_readable_pipe(const basic_readable_pipe&) = delete;-  basic_readable_pipe& operator=(const basic_readable_pipe&) = delete;+  basic_readable_pipe(const basic_readable_pipe&) ASIO_DELETED;+  basic_readable_pipe& operator=(const basic_readable_pipe&) ASIO_DELETED;    class initiate_async_read_some   {@@ -584,13 +593,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_seq_packet_socket.hpp view
@@ -2,7 +2,7 @@ // basic_seq_packet_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -111,9 +111,9 @@    */   template <typename ExecutionContext>   explicit basic_seq_packet_socket(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context)   {   }@@ -154,10 +154,10 @@   template <typename ExecutionContext>   basic_seq_packet_socket(ExecutionContext& context,       const protocol_type& protocol,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_socket<Protocol, Executor>(context, protocol)   {   }@@ -202,9 +202,9 @@   template <typename ExecutionContext>   basic_seq_packet_socket(ExecutionContext& context,       const endpoint_type& endpoint,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context, endpoint)   {   }@@ -247,13 +247,14 @@   template <typename ExecutionContext>   basic_seq_packet_socket(ExecutionContext& context,       const protocol_type& protocol, const native_handle_type& native_socket,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context, protocol, native_socket)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_seq_packet_socket from another.   /**    * This constructor moves a sequenced packet socket from one object to@@ -266,7 +267,7 @@    * constructed using the @c basic_seq_packet_socket(const executor_type&)    * constructor.    */-  basic_seq_packet_socket(basic_seq_packet_socket&& other) noexcept+  basic_seq_packet_socket(basic_seq_packet_socket&& other) ASIO_NOEXCEPT     : basic_socket<Protocol, Executor>(std::move(other))   {   }@@ -304,10 +305,10 @@    */   template <typename Protocol1, typename Executor1>   basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Protocol1, Protocol>::value           && is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(std::move(other))   {   }@@ -326,15 +327,16 @@    * constructor.    */   template <typename Protocol1, typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Protocol1, Protocol>::value       && is_convertible<Executor1, Executor>::value,     basic_seq_packet_socket&-  > operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other)+  >::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other)   {     basic_socket<Protocol, Executor>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the socket.   /**@@ -430,7 +432,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -457,15 +459,17 @@   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         std::size_t)) WriteToken-          = default_completion_token_t<executor_type>>-  auto async_send(const ConstBufferSequence& buffers,+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send(const ConstBufferSequence& buffers,       socket_base::message_flags flags,-      WriteToken&& token-        = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_send>(), token, buffers, flags))+          declval<initiate_async_send>(), token, buffers, flags)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -620,7 +624,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -647,15 +651,19 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive(const MutableBufferSequence& buffers,+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive(const MutableBufferSequence& buffers,       socket_base::message_flags& out_flags,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive_with_flags>(), token,-          buffers, socket_base::message_flags(0), &out_flags))+          buffers, socket_base::message_flags(0), &out_flags)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -694,7 +702,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -723,16 +731,20 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive(const MutableBufferSequence& buffers,+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive(const MutableBufferSequence& buffers,       socket_base::message_flags in_flags,       socket_base::message_flags& out_flags,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive_with_flags>(),-          token, buffers, in_flags, &out_flags))+          token, buffers, in_flags, &out_flags)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -742,9 +754,9 @@  private:   // Disallow copying and assignment.-  basic_seq_packet_socket(const basic_seq_packet_socket&) = delete;+  basic_seq_packet_socket(const basic_seq_packet_socket&) ASIO_DELETED;   basic_seq_packet_socket& operator=(-      const basic_seq_packet_socket&) = delete;+      const basic_seq_packet_socket&) ASIO_DELETED;    class initiate_async_send   {@@ -756,13 +768,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers,         socket_base::message_flags flags) const     {@@ -790,13 +802,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers,         socket_base::message_flags in_flags,         socket_base::message_flags* out_flags) const
link/modules/asio-standalone/asio/include/asio/basic_serial_port.hpp view
@@ -2,7 +2,7 @@ // basic_serial_port.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -22,7 +22,6 @@   || defined(GENERATING_DOCUMENTATION)  #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -39,6 +38,10 @@ # include "asio/detail/posix_serial_port_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -109,10 +112,10 @@    */   template <typename ExecutionContext>   explicit basic_serial_port(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {   }@@ -151,9 +154,9 @@    */   template <typename ExecutionContext>   basic_serial_port(ExecutionContext& context, const char* device,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -195,9 +198,9 @@    */   template <typename ExecutionContext>   basic_serial_port(ExecutionContext& context, const std::string& device,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -244,9 +247,9 @@   template <typename ExecutionContext>   basic_serial_port(ExecutionContext& context,       const native_handle_type& native_serial_port,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -255,6 +258,7 @@     asio::detail::throw_error(ec, "assign");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_serial_port from another.   /**    * This constructor moves a serial port from one object to another.@@ -306,10 +310,10 @@    */   template <typename Executor1>   basic_serial_port(basic_serial_port<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(std::move(other.impl_))   {   }@@ -327,15 +331,16 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_serial_port&-  > operator=(basic_serial_port<Executor1>&& other)+  >::type operator=(basic_serial_port<Executor1>&& other)   {     basic_serial_port tmp(std::move(other));     impl_ = std::move(tmp.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the serial port.   /**@@ -348,7 +353,7 @@   }    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -724,7 +729,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -755,13 +760,17 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_write_some>(), token, buffers))+          declval<initiate_async_write_some>(), token, buffers)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -854,7 +863,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -886,13 +895,17 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_read_some>(), token, buffers))+          declval<initiate_async_read_some>(), token, buffers)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -901,8 +914,8 @@  private:   // Disallow copying and assignment.-  basic_serial_port(const basic_serial_port&) = delete;-  basic_serial_port& operator=(const basic_serial_port&) = delete;+  basic_serial_port(const basic_serial_port&) ASIO_DELETED;+  basic_serial_port& operator=(const basic_serial_port&) ASIO_DELETED;    class initiate_async_write_some   {@@ -914,13 +927,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler@@ -947,13 +960,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_signal_set.hpp view
@@ -2,7 +2,7 @@ // basic_signal_set.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -134,10 +134,10 @@    */   template <typename ExecutionContext>   explicit basic_signal_set(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {   }@@ -180,10 +180,10 @@    */   template <typename ExecutionContext>   basic_signal_set(ExecutionContext& context, int signal_number_1,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {     asio::error_code ec;@@ -239,10 +239,10 @@   template <typename ExecutionContext>   basic_signal_set(ExecutionContext& context, int signal_number_1,       int signal_number_2,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {     asio::error_code ec;@@ -308,10 +308,10 @@   template <typename ExecutionContext>   basic_signal_set(ExecutionContext& context, int signal_number_1,       int signal_number_2, int signal_number_3,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {     asio::error_code ec;@@ -334,7 +334,7 @@   }    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -573,7 +573,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, int) @endcode@@ -587,20 +587,18 @@    * @li @c cancellation_type::partial    *    * @li @c cancellation_type::total-   *-   * @note Unlike the POSIX function @c signal, @c async_wait executes its-   * completion handler as specified in the @ref async_op_requirements. This-   * means it places no async-signal safety restrictions on what work can be-   * performed in a completion handler.    */   template <     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code, int))-      SignalToken = default_completion_token_t<executor_type>>-  auto async_wait(-      SignalToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      SignalToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(SignalToken,+      void (asio::error_code, int))+  async_wait(+      ASIO_MOVE_ARG(SignalToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<SignalToken, void (asio::error_code, int)>(-        declval<initiate_async_wait>(), token))+          declval<initiate_async_wait>(), token)))   {     return async_initiate<SignalToken, void (asio::error_code, int)>(         initiate_async_wait(this), token);@@ -608,8 +606,8 @@  private:   // Disallow copying and assignment.-  basic_signal_set(const basic_signal_set&) = delete;-  basic_signal_set& operator=(const basic_signal_set&) = delete;+  basic_signal_set(const basic_signal_set&) ASIO_DELETED;+  basic_signal_set& operator=(const basic_signal_set&) ASIO_DELETED;    class initiate_async_wait   {@@ -621,13 +619,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename SignalHandler>-    void operator()(SignalHandler&& handler) const+    void operator()(ASIO_MOVE_ARG(SignalHandler) handler) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a SignalHandler.
link/modules/asio-standalone/asio/include/asio/basic_socket.hpp view
@@ -2,7 +2,7 @@ // basic_socket.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -15,7 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <utility> #include "asio/any_io_executor.hpp" #include "asio/detail/config.hpp" #include "asio/async_result.hpp"@@ -39,6 +38,10 @@ # include "asio/detail/reactive_socket_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -131,9 +134,9 @@    */   template <typename ExecutionContext>   explicit basic_socket(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {   }@@ -171,10 +174,10 @@    */   template <typename ExecutionContext>   basic_socket(ExecutionContext& context, const protocol_type& protocol,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {     asio::error_code ec;@@ -226,9 +229,9 @@    */   template <typename ExecutionContext>   basic_socket(ExecutionContext& context, const endpoint_type& endpoint,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -279,9 +282,9 @@   template <typename ExecutionContext>   basic_socket(ExecutionContext& context, const protocol_type& protocol,       const native_handle_type& native_socket,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -290,6 +293,7 @@     asio::detail::throw_error(ec, "assign");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_socket from another.   /**    * This constructor moves a socket from one object to another.@@ -300,7 +304,7 @@    * @note Following the move, the moved-from object is in the same state as if    * constructed using the @c basic_socket(const executor_type&) constructor.    */-  basic_socket(basic_socket&& other) noexcept+  basic_socket(basic_socket&& other) ASIO_NOEXCEPT     : impl_(std::move(other.impl_))   {   }@@ -337,10 +341,10 @@    */   template <typename Protocol1, typename Executor1>   basic_socket(basic_socket<Protocol1, Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Protocol1, Protocol>::value           && is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : impl_(std::move(other.impl_))   {   }@@ -356,19 +360,20 @@    * constructed using the @c basic_socket(const executor_type&) constructor.    */   template <typename Protocol1, typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Protocol1, Protocol>::value       && is_convertible<Executor1, Executor>::value,     basic_socket&-  > operator=(basic_socket<Protocol1, Executor1>&& other)+  >::type operator=(basic_socket<Protocol1, Executor1>&& other)   {     basic_socket tmp(std::move(other));     impl_ = std::move(tmp.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -927,7 +932,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -962,13 +967,16 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        ConnectToken = default_completion_token_t<executor_type>>-  auto async_connect(const endpoint_type& peer_endpoint,-      ConnectToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        ConnectToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ConnectToken,+      void (asio::error_code))+  async_connect(const endpoint_type& peer_endpoint,+      ASIO_MOVE_ARG(ConnectToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ConnectToken, void (asio::error_code)>(-        declval<initiate_async_connect>(), token,-        peer_endpoint, declval<asio::error_code&>()))+          declval<initiate_async_connect>(), token,+          peer_endpoint, declval<asio::error_code&>())))   {     asio::error_code open_ec;     if (!is_open())@@ -1779,7 +1787,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -1813,12 +1821,15 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        WaitToken = default_completion_token_t<executor_type>>-  auto async_wait(wait_type w,-      WaitToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+      void (asio::error_code))+  async_wait(wait_type w,+      ASIO_MOVE_ARG(WaitToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WaitToken, void (asio::error_code)>(-          declval<initiate_async_wait>(), token, w))+          declval<initiate_async_wait>(), token, w)))   {     return async_initiate<WaitToken, void (asio::error_code)>(         initiate_async_wait(this), token, w);@@ -1850,8 +1861,8 @@  private:   // Disallow copying and assignment.-  basic_socket(const basic_socket&) = delete;-  basic_socket& operator=(const basic_socket&) = delete;+  basic_socket(const basic_socket&) ASIO_DELETED;+  basic_socket& operator=(const basic_socket&) ASIO_DELETED;    class initiate_async_connect   {@@ -1863,13 +1874,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ConnectHandler>-    void operator()(ConnectHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ConnectHandler) handler,         const endpoint_type& peer_endpoint,         const asio::error_code& open_ec) const     {@@ -1881,7 +1892,7 @@       {           asio::post(self_->impl_.get_executor(),               asio::detail::bind_handler(-                static_cast<ConnectHandler&&>(handler), open_ec));+                ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));       }       else       {@@ -1906,13 +1917,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WaitHandler>-    void operator()(WaitHandler&& handler, wait_type w) const+    void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WaitHandler.
link/modules/asio-standalone/asio/include/asio/basic_socket_acceptor.hpp view
@@ -2,7 +2,7 @@ // basic_socket_acceptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -15,7 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <utility> #include "asio/detail/config.hpp" #include "asio/any_io_executor.hpp" #include "asio/basic_socket.hpp"@@ -38,6 +37,10 @@ # include "asio/detail/reactive_socket_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -148,9 +151,9 @@    */   template <typename ExecutionContext>   explicit basic_socket_acceptor(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {   }@@ -190,10 +193,10 @@   template <typename ExecutionContext>   basic_socket_acceptor(ExecutionContext& context,       const protocol_type& protocol,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {     asio::error_code ec;@@ -279,9 +282,9 @@   template <typename ExecutionContext>   basic_socket_acceptor(ExecutionContext& context,       const endpoint_type& endpoint, bool reuse_addr = true,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -344,9 +347,9 @@   template <typename ExecutionContext>   basic_socket_acceptor(ExecutionContext& context,       const protocol_type& protocol, const native_handle_type& native_acceptor,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -355,6 +358,7 @@     asio::detail::throw_error(ec, "assign");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_socket_acceptor from another.   /**    * This constructor moves an acceptor from one object to another.@@ -366,7 +370,7 @@    * constructed using the @c basic_socket_acceptor(const executor_type&)    * constructor.    */-  basic_socket_acceptor(basic_socket_acceptor&& other) noexcept+  basic_socket_acceptor(basic_socket_acceptor&& other) ASIO_NOEXCEPT     : impl_(std::move(other.impl_))   {   }@@ -406,10 +410,10 @@    */   template <typename Protocol1, typename Executor1>   basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Protocol1, Protocol>::value           && is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : impl_(std::move(other.impl_))   {   }@@ -427,16 +431,17 @@    * constructor.    */   template <typename Protocol1, typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Protocol1, Protocol>::value       && is_convertible<Executor1, Executor>::value,     basic_socket_acceptor&-  > operator=(basic_socket_acceptor<Protocol1, Executor1>&& other)+  >::type operator=(basic_socket_acceptor<Protocol1, Executor1>&& other)   {     basic_socket_acceptor tmp(std::move(other));     impl_ = std::move(tmp.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the acceptor.   /**@@ -449,7 +454,7 @@   }    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -1213,7 +1218,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -1249,12 +1254,15 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        WaitToken = default_completion_token_t<executor_type>>-  auto async_wait(wait_type w,-      WaitToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+      void (asio::error_code))+  async_wait(wait_type w,+      ASIO_MOVE_ARG(WaitToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WaitToken, void (asio::error_code)>(-        declval<initiate_async_wait>(), token, w))+          declval<initiate_async_wait>(), token, w)))   {     return async_initiate<WaitToken, void (asio::error_code)>(         initiate_async_wait(this), token, w);@@ -1281,9 +1289,9 @@    */   template <typename Protocol1, typename Executor1>   void accept(basic_socket<Protocol1, Executor1>& peer,-      constraint_t<+      typename constraint<         is_convertible<Protocol, Protocol1>::value-      > = 0)+      >::type = 0)   {     asio::error_code ec;     impl_.get_service().accept(impl_.get_implementation(),@@ -1317,9 +1325,9 @@   template <typename Protocol1, typename Executor1>   ASIO_SYNC_OP_VOID accept(       basic_socket<Protocol1, Executor1>& peer, asio::error_code& ec,-      constraint_t<+      typename constraint<         is_convertible<Protocol, Protocol1>::value-      > = 0)+      >::type = 0)   {     impl_.get_service().accept(impl_.get_implementation(),         peer, static_cast<endpoint_type*>(0), ec);@@ -1348,7 +1356,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -1383,16 +1391,19 @@    */   template <typename Protocol1, typename Executor1,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        AcceptToken = default_completion_token_t<executor_type>>-  auto async_accept(basic_socket<Protocol1, Executor1>& peer,-      AcceptToken&& token = default_completion_token_t<executor_type>(),-      constraint_t<+        AcceptToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(AcceptToken,+      void (asio::error_code))+  async_accept(basic_socket<Protocol1, Executor1>& peer,+      ASIO_MOVE_ARG(AcceptToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+      typename constraint<         is_convertible<Protocol, Protocol1>::value-      > = 0)-    -> decltype(+      >::type = 0)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<AcceptToken, void (asio::error_code)>(-        declval<initiate_async_accept>(), token,-        &peer, static_cast<endpoint_type*>(0)))+          declval<initiate_async_accept>(), token,+          &peer, static_cast<endpoint_type*>(0))))   {     return async_initiate<AcceptToken, void (asio::error_code)>(         initiate_async_accept(this), token,@@ -1496,7 +1507,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -1513,19 +1524,23 @@    */   template <typename Executor1,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        AcceptToken = default_completion_token_t<executor_type>>-  auto async_accept(basic_socket<protocol_type, Executor1>& peer,+        AcceptToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(AcceptToken,+      void (asio::error_code))+  async_accept(basic_socket<protocol_type, Executor1>& peer,       endpoint_type& peer_endpoint,-      AcceptToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(AcceptToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<AcceptToken, void (asio::error_code)>(-        declval<initiate_async_accept>(), token, &peer, &peer_endpoint))+          declval<initiate_async_accept>(), token, &peer, &peer_endpoint)))   {     return async_initiate<AcceptToken, void (asio::error_code)>(         initiate_async_accept(this), token, &peer, &peer_endpoint);   } #endif // !defined(ASIO_NO_EXTENSIONS) +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Accept a new connection.   /**    * This function is used to accept a new connection from a peer. The function@@ -1616,7 +1631,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code,@@ -1655,17 +1670,22 @@       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         typename Protocol::socket::template rebind_executor<           executor_type>::other)) MoveAcceptToken-            = default_completion_token_t<executor_type>>-  auto async_accept(-      MoveAcceptToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+            ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+      void (asio::error_code,+        typename Protocol::socket::template+          rebind_executor<executor_type>::other))+  async_accept(+      ASIO_MOVE_ARG(MoveAcceptToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<MoveAcceptToken,         void (asio::error_code, typename Protocol::socket::template           rebind_executor<executor_type>::other)>(             declval<initiate_async_move_accept>(), token,-            declval<const executor_type&>(), static_cast<endpoint_type*>(0),+            declval<executor_type>(), static_cast<endpoint_type*>(0),             static_cast<typename Protocol::socket::template-              rebind_executor<executor_type>::other*>(0)))+              rebind_executor<executor_type>::other*>(0))))   {     return async_initiate<MoveAcceptToken,       void (asio::error_code, typename Protocol::socket::template@@ -1702,10 +1722,10 @@   template <typename Executor1>   typename Protocol::socket::template rebind_executor<Executor1>::other   accept(const Executor1& ex,-      constraint_t<+      typename constraint<         is_executor<Executor1>::value           || execution::is_executor<Executor1>::value-      > = 0)+      >::type = 0)   {     asio::error_code ec;     typename Protocol::socket::template@@ -1742,9 +1762,9 @@   typename Protocol::socket::template rebind_executor<       typename ExecutionContext::executor_type>::other   accept(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)   {     asio::error_code ec;     typename Protocol::socket::template rebind_executor<@@ -1785,10 +1805,10 @@   template <typename Executor1>   typename Protocol::socket::template rebind_executor<Executor1>::other   accept(const Executor1& ex, asio::error_code& ec,-      constraint_t<+      typename constraint<         is_executor<Executor1>::value           || execution::is_executor<Executor1>::value-      > = 0)+      >::type = 0)   {     typename Protocol::socket::template       rebind_executor<Executor1>::other peer(ex);@@ -1828,9 +1848,9 @@   typename Protocol::socket::template rebind_executor<       typename ExecutionContext::executor_type>::other   accept(ExecutionContext& context, asio::error_code& ec,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)   {     typename Protocol::socket::template rebind_executor<         typename ExecutionContext::executor_type>::other peer(context);@@ -1866,7 +1886,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code,@@ -1904,17 +1924,22 @@   template <typename Executor1,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         typename Protocol::socket::template rebind_executor<-          constraint_t<is_executor<Executor1>::value+          typename constraint<is_executor<Executor1>::value             || execution::is_executor<Executor1>::value,-              Executor1>>::other)) MoveAcceptToken-                = default_completion_token_t<executor_type>>-  auto async_accept(const Executor1& ex,-      MoveAcceptToken&& token = default_completion_token_t<executor_type>(),-      constraint_t<+              Executor1>::type>::other)) MoveAcceptToken+                ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+      void (asio::error_code,+        typename Protocol::socket::template rebind_executor<+          Executor1>::other))+  async_accept(const Executor1& ex,+      ASIO_MOVE_ARG(MoveAcceptToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+      typename constraint<         is_executor<Executor1>::value           || execution::is_executor<Executor1>::value-      > = 0)-    -> decltype(+      >::type = 0)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<MoveAcceptToken,         void (asio::error_code,           typename Protocol::socket::template rebind_executor<@@ -1922,7 +1947,7 @@               declval<initiate_async_move_accept>(), token,               ex, static_cast<endpoint_type*>(0),               static_cast<typename Protocol::socket::template-                rebind_executor<Executor1>::other*>(0)))+                rebind_executor<Executor1>::other*>(0))))   {     return async_initiate<MoveAcceptToken,       void (asio::error_code,@@ -1962,7 +1987,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code,@@ -2001,13 +2026,18 @@       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         typename Protocol::socket::template rebind_executor<           typename ExecutionContext::executor_type>::other)) MoveAcceptToken-            = default_completion_token_t<executor_type>>-  auto async_accept(ExecutionContext& context,-      MoveAcceptToken&& token = default_completion_token_t<executor_type>(),-      constraint_t<+            ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+      void (asio::error_code,+        typename Protocol::socket::template rebind_executor<+          typename ExecutionContext::executor_type>::other))+  async_accept(ExecutionContext& context,+      ASIO_MOVE_ARG(MoveAcceptToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)-    -> decltype(+      >::type = 0)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<MoveAcceptToken,         void (asio::error_code,           typename Protocol::socket::template rebind_executor<@@ -2015,7 +2045,7 @@               declval<initiate_async_move_accept>(), token,               context.get_executor(), static_cast<endpoint_type*>(0),               static_cast<typename Protocol::socket::template rebind_executor<-                typename ExecutionContext::executor_type>::other*>(0)))+                typename ExecutionContext::executor_type>::other*>(0))))   {     return async_initiate<MoveAcceptToken,       void (asio::error_code,@@ -2132,7 +2162,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code,@@ -2172,17 +2202,22 @@       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         typename Protocol::socket::template rebind_executor<           executor_type>::other)) MoveAcceptToken-            = default_completion_token_t<executor_type>>-  auto async_accept(endpoint_type& peer_endpoint,-      MoveAcceptToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+            ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+      void (asio::error_code,+        typename Protocol::socket::template+          rebind_executor<executor_type>::other))+  async_accept(endpoint_type& peer_endpoint,+      ASIO_MOVE_ARG(MoveAcceptToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<MoveAcceptToken,         void (asio::error_code, typename Protocol::socket::template           rebind_executor<executor_type>::other)>(             declval<initiate_async_move_accept>(), token,-            declval<const executor_type&>(), &peer_endpoint,+            declval<executor_type>(), &peer_endpoint,             static_cast<typename Protocol::socket::template-              rebind_executor<executor_type>::other*>(0)))+              rebind_executor<executor_type>::other*>(0))))   {     return async_initiate<MoveAcceptToken,       void (asio::error_code, typename Protocol::socket::template@@ -2224,10 +2259,10 @@   template <typename Executor1>   typename Protocol::socket::template rebind_executor<Executor1>::other   accept(const Executor1& ex, endpoint_type& peer_endpoint,-      constraint_t<+      typename constraint<         is_executor<Executor1>::value           || execution::is_executor<Executor1>::value-      > = 0)+      >::type = 0)   {     asio::error_code ec;     typename Protocol::socket::template@@ -2270,9 +2305,9 @@   typename Protocol::socket::template rebind_executor<       typename ExecutionContext::executor_type>::other   accept(ExecutionContext& context, endpoint_type& peer_endpoint,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)   {     asio::error_code ec;     typename Protocol::socket::template rebind_executor<@@ -2320,10 +2355,10 @@   typename Protocol::socket::template rebind_executor<Executor1>::other   accept(const executor_type& ex,       endpoint_type& peer_endpoint, asio::error_code& ec,-      constraint_t<+      typename constraint<         is_executor<Executor1>::value           || execution::is_executor<Executor1>::value-      > = 0)+      >::type = 0)   {     typename Protocol::socket::template       rebind_executor<Executor1>::other peer(ex);@@ -2370,9 +2405,9 @@       typename ExecutionContext::executor_type>::other   accept(ExecutionContext& context,       endpoint_type& peer_endpoint, asio::error_code& ec,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)   {     typename Protocol::socket::template rebind_executor<         typename ExecutionContext::executor_type>::other peer(context);@@ -2414,7 +2449,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code,@@ -2453,24 +2488,29 @@   template <typename Executor1,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         typename Protocol::socket::template rebind_executor<-          constraint_t<is_executor<Executor1>::value+          typename constraint<is_executor<Executor1>::value             || execution::is_executor<Executor1>::value,-              Executor1>>::other)) MoveAcceptToken-                = default_completion_token_t<executor_type>>-  auto async_accept(const Executor1& ex, endpoint_type& peer_endpoint,-      MoveAcceptToken&& token = default_completion_token_t<executor_type>(),-      constraint_t<+              Executor1>::type>::other)) MoveAcceptToken+                ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+      void (asio::error_code,+        typename Protocol::socket::template rebind_executor<+          Executor1>::other))+  async_accept(const Executor1& ex, endpoint_type& peer_endpoint,+      ASIO_MOVE_ARG(MoveAcceptToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+      typename constraint<         is_executor<Executor1>::value           || execution::is_executor<Executor1>::value-      > = 0)-    -> decltype(+      >::type = 0)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<MoveAcceptToken,         void (asio::error_code,           typename Protocol::socket::template rebind_executor<             Executor1>::other)>(           declval<initiate_async_move_accept>(), token, ex, &peer_endpoint,           static_cast<typename Protocol::socket::template-            rebind_executor<Executor1>::other*>(0)))+            rebind_executor<Executor1>::other*>(0))))   {     return async_initiate<MoveAcceptToken,       void (asio::error_code,@@ -2514,7 +2554,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code,@@ -2554,13 +2594,19 @@       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         typename Protocol::socket::template rebind_executor<           typename ExecutionContext::executor_type>::other)) MoveAcceptToken-            = default_completion_token_t<executor_type>>-  auto async_accept(ExecutionContext& context, endpoint_type& peer_endpoint,-      MoveAcceptToken&& token = default_completion_token_t<executor_type>(),-      constraint_t<+            ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(MoveAcceptToken,+      void (asio::error_code,+        typename Protocol::socket::template rebind_executor<+          typename ExecutionContext::executor_type>::other))+  async_accept(ExecutionContext& context,+      endpoint_type& peer_endpoint,+      ASIO_MOVE_ARG(MoveAcceptToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type),+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)-    -> decltype(+      >::type = 0)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<MoveAcceptToken,         void (asio::error_code,           typename Protocol::socket::template rebind_executor<@@ -2568,7 +2614,7 @@               declval<initiate_async_move_accept>(), token,               context.get_executor(), &peer_endpoint,               static_cast<typename Protocol::socket::template rebind_executor<-                typename ExecutionContext::executor_type>::other*>(0)))+                typename ExecutionContext::executor_type>::other*>(0))))   {     return async_initiate<MoveAcceptToken,       void (asio::error_code,@@ -2579,12 +2625,13 @@             static_cast<typename Protocol::socket::template rebind_executor<               typename ExecutionContext::executor_type>::other*>(0));   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  private:   // Disallow copying and assignment.-  basic_socket_acceptor(const basic_socket_acceptor&) = delete;+  basic_socket_acceptor(const basic_socket_acceptor&) ASIO_DELETED;   basic_socket_acceptor& operator=(-      const basic_socket_acceptor&) = delete;+      const basic_socket_acceptor&) ASIO_DELETED;    class initiate_async_wait   {@@ -2596,13 +2643,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WaitHandler>-    void operator()(WaitHandler&& handler, wait_type w) const+    void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WaitHandler.@@ -2628,13 +2675,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename AcceptHandler, typename Protocol1, typename Executor1>-    void operator()(AcceptHandler&& handler,+    void operator()(ASIO_MOVE_ARG(AcceptHandler) handler,         basic_socket<Protocol1, Executor1>* peer,         endpoint_type* peer_endpoint) const     {@@ -2662,13 +2709,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename MoveAcceptHandler, typename Executor1, typename Socket>-    void operator()(MoveAcceptHandler&& handler,+    void operator()(ASIO_MOVE_ARG(MoveAcceptHandler) handler,         const Executor1& peer_ex, endpoint_type* peer_endpoint, Socket*) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_socket_iostream.hpp view
@@ -2,7 +2,7 @@ // basic_socket_iostream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,6 +23,55 @@ #include <ostream> #include "asio/basic_socket_streambuf.hpp" +#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)++# include "asio/detail/variadic_templates.hpp"++// A macro that should expand to:+//   template <typename T1, ..., typename Tn>+//   explicit basic_socket_iostream(T1 x1, ..., Tn xn)+//     : std::basic_iostream<char>(+//         &this->detail::socket_iostream_base<+//           Protocol, Clock, WaitTraits>::streambuf_)+//   {+//     if (rdbuf()->connect(x1, ..., xn) == 0)+//       this->setstate(std::ios_base::failbit);+//   }+// This macro should only persist within this file.++# define ASIO_PRIVATE_CTR_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  explicit basic_socket_iostream(ASIO_VARIADIC_BYVAL_PARAMS(n)) \+    : std::basic_iostream<char>( \+        &this->detail::socket_iostream_base< \+          Protocol, Clock, WaitTraits>::streambuf_) \+  { \+    this->setf(std::ios_base::unitbuf); \+    if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \+      this->setstate(std::ios_base::failbit); \+  } \+  /**/++// A macro that should expand to:+//   template <typename T1, ..., typename Tn>+//   void connect(T1 x1, ..., Tn xn)+//   {+//     if (rdbuf()->connect(x1, ..., xn) == 0)+//       this->setstate(std::ios_base::failbit);+//   }+// This macro should only persist within this file.++# define ASIO_PRIVATE_CONNECT_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  void connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \+  { \+    if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \+      this->setstate(std::ios_base::failbit); \+  } \+  /**/++#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -38,6 +87,7 @@   {   } +#if defined(ASIO_HAS_MOVE)   socket_iostream_base(socket_iostream_base&& other)     : streambuf_(std::move(other.streambuf_))   {@@ -53,6 +103,7 @@     streambuf_ = std::move(other.streambuf_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    basic_socket_streambuf<Protocol, Clock, WaitTraits> streambuf_; };@@ -64,8 +115,16 @@  // Forward declaration with defaulted arguments. template <typename Protocol,+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+  && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+    typename Clock = boost::posix_time::ptime,+    typename WaitTraits = time_traits<Clock> >+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+      // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)     typename Clock = chrono::steady_clock,-    typename WaitTraits = wait_traits<Clock>>+    typename WaitTraits = wait_traits<Clock> >+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+       // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) class basic_socket_iostream;  #endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)@@ -74,7 +133,7 @@ #if defined(GENERATING_DOCUMENTATION) template <typename Protocol,     typename Clock = chrono::steady_clock,-    typename WaitTraits = wait_traits<Clock>>+    typename WaitTraits = wait_traits<Clock> > #else // defined(GENERATING_DOCUMENTATION) template <typename Protocol, typename Clock, typename WaitTraits> #endif // defined(GENERATING_DOCUMENTATION)@@ -83,7 +142,16 @@     public std::basic_iostream<char> { private:+  // These typedefs are intended keep this class's implementation independent+  // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+  && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+  typedef WaitTraits traits_helper;+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+      // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)   typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+       // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)  public:   /// The protocol type.@@ -96,12 +164,22 @@   typedef Clock clock_type;  #if defined(GENERATING_DOCUMENTATION)+  /// (Deprecated: Use time_point.) The time type.+  typedef typename WaitTraits::time_type time_type;+   /// The time type.   typedef typename WaitTraits::time_point time_point; +  /// (Deprecated: Use duration.) The duration type.+  typedef typename WaitTraits::duration_type duration_type;+   /// The duration type.   typedef typename WaitTraits::duration duration; #else+# if !defined(ASIO_NO_DEPRECATED)+  typedef typename traits_helper::time_type time_type;+  typedef typename traits_helper::duration_type duration_type;+# endif // !defined(ASIO_NO_DEPRECATED)   typedef typename traits_helper::time_type time_point;   typedef typename traits_helper::duration_type duration; #endif@@ -115,6 +193,7 @@     this->setf(std::ios_base::unitbuf);   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Construct a basic_socket_iostream from the supplied socket.   explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)     : detail::socket_iostream_base<@@ -126,6 +205,8 @@     this->setf(std::ios_base::unitbuf);   } +#if defined(ASIO_HAS_STD_IOSTREAM_MOVE) \+  || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_socket_iostream from another.   basic_socket_iostream(basic_socket_iostream&& other)     : detail::socket_iostream_base<@@ -144,13 +225,20 @@         Protocol, Clock, WaitTraits>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_STD_IOSTREAM_MOVE)+       //   || defined(GENERATING_DOCUMENTATION)+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) +#if defined(GENERATING_DOCUMENTATION)   /// Establish a connection to an endpoint corresponding to a resolver query.   /**    * This constructor automatically establishes a connection based on the    * supplied resolver query parameters. The arguments are used to construct    * a resolver query object.    */+  template <typename T1, ..., typename TN>+  explicit basic_socket_iostream(T1 t1, ..., TN tn);+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)   template <typename... T>   explicit basic_socket_iostream(T... x)     : std::basic_iostream<char>(@@ -161,19 +249,29 @@     if (rdbuf()->connect(x...) == 0)       this->setstate(std::ios_base::failbit);   }+#else+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CTR_DEF)+#endif +#if defined(GENERATING_DOCUMENTATION)   /// Establish a connection to an endpoint corresponding to a resolver query.   /**    * This function automatically establishes a connection based on the supplied    * resolver query parameters. The arguments are used to construct a resolver    * query object.    */+  template <typename T1, ..., typename TN>+  void connect(T1 t1, ..., TN tn);+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)   template <typename... T>   void connect(T... x)   {     if (rdbuf()->connect(x...) == 0)       this->setstate(std::ios_base::failbit);   }+#else+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF)+#endif    /// Close the connection.   void close()@@ -213,6 +311,18 @@     return rdbuf()->error();   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use expiry().) Get the stream's expiry time as an absolute+  /// time.+  /**+   * @return An absolute time value representing the stream's expiry time.+   */+  time_point expires_at() const+  {+    return rdbuf()->expires_at();+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Get the stream's expiry time as an absolute time.   /**    * @return An absolute time value representing the stream's expiry time.@@ -250,16 +360,47 @@     rdbuf()->expires_after(expiry_time);   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use expiry().) Get the stream's expiry time relative to now.+  /**+   * @return A relative time value representing the stream's expiry time.+   */+  duration expires_from_now() const+  {+    return rdbuf()->expires_from_now();+  }++  /// (Deprecated: Use expires_after().) Set the stream's expiry time relative+  /// to now.+  /**+   * This function sets the expiry time associated with the stream. Stream+   * operations performed after this time (where the operations cannot be+   * completed using the internal buffers) will fail with the error+   * asio::error::operation_aborted.+   *+   * @param expiry_time The expiry time to be used for the timer.+   */+  void expires_from_now(const duration& expiry_time)+  {+    rdbuf()->expires_from_now(expiry_time);+  }+#endif // !defined(ASIO_NO_DEPRECATED)+ private:   // Disallow copying and assignment.-  basic_socket_iostream(const basic_socket_iostream&) = delete;+  basic_socket_iostream(const basic_socket_iostream&) ASIO_DELETED;   basic_socket_iostream& operator=(-      const basic_socket_iostream&) = delete;+      const basic_socket_iostream&) ASIO_DELETED; };  } // namespace asio  #include "asio/detail/pop_options.hpp"++#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)+# undef ASIO_PRIVATE_CTR_DEF+# undef ASIO_PRIVATE_CONNECT_DEF+#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)  #endif // !defined(ASIO_NO_IOSTREAM) 
link/modules/asio-standalone/asio/include/asio/basic_socket_streambuf.hpp view
@@ -2,7 +2,7 @@ // basic_socket_streambuf.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -27,8 +27,48 @@ #include "asio/detail/memory.hpp" #include "asio/detail/throw_error.hpp" #include "asio/io_context.hpp"-#include "asio/steady_timer.hpp" +#if defined(ASIO_HAS_BOOST_DATE_TIME) \+  && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+# include "asio/detail/deadline_timer_service.hpp"+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+      // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+# include "asio/steady_timer.hpp"+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+       // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)++#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)++# include "asio/detail/variadic_templates.hpp"++// A macro that should expand to:+//   template <typename T1, ..., typename Tn>+//   basic_socket_streambuf* connect(T1 x1, ..., Tn xn)+//   {+//     init_buffers();+//     typedef typename Protocol::resolver resolver_type;+//     resolver_type resolver(socket().get_executor());+//     connect_to_endpoints(+//         resolver.resolve(x1, ..., xn, ec_));+//     return !ec_ ? this : 0;+//   }+// This macro should only persist within this file.++# define ASIO_PRIVATE_CONNECT_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  basic_socket_streambuf* connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \+  { \+    init_buffers(); \+    typedef typename Protocol::resolver resolver_type; \+    resolver_type resolver(socket().get_executor()); \+    connect_to_endpoints( \+        resolver.resolve(ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \+    return !ec_ ? this : 0; \+  } \+  /**/++#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -73,8 +113,16 @@  // Forward declaration with defaulted arguments. template <typename Protocol,+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+  && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+    typename Clock = boost::posix_time::ptime,+    typename WaitTraits = time_traits<Clock> >+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+      // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)     typename Clock = chrono::steady_clock,-    typename WaitTraits = wait_traits<Clock>>+    typename WaitTraits = wait_traits<Clock> >+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+       // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM) class basic_socket_streambuf;  #endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)@@ -83,7 +131,7 @@ #if defined(GENERATING_DOCUMENTATION) template <typename Protocol,     typename Clock = chrono::steady_clock,-    typename WaitTraits = wait_traits<Clock>>+    typename WaitTraits = wait_traits<Clock> > #else // defined(GENERATING_DOCUMENTATION) template <typename Protocol, typename Clock, typename WaitTraits> #endif // defined(GENERATING_DOCUMENTATION)@@ -91,10 +139,23 @@   : public std::streambuf,     private detail::socket_streambuf_io_context,     private detail::socket_streambuf_buffers,+#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)     private basic_socket<Protocol>+#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)+    public basic_socket<Protocol>+#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) { private:+  // These typedefs are intended keep this class's implementation independent+  // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+  && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+  typedef WaitTraits traits_helper;+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+      // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)   typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+       // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)  public:   /// The protocol type.@@ -107,12 +168,22 @@   typedef Clock clock_type;  #if defined(GENERATING_DOCUMENTATION)+  /// (Deprecated: Use time_point.) The time type.+  typedef typename WaitTraits::time_type time_type;+   /// The time type.   typedef typename WaitTraits::time_point time_point; +  /// (Deprecated: Use duration.) The duration type.+  typedef typename WaitTraits::duration_type duration_type;+   /// The duration type.   typedef typename WaitTraits::duration duration; #else+# if !defined(ASIO_NO_DEPRECATED)+  typedef typename traits_helper::time_type time_type;+  typedef typename traits_helper::duration_type duration_type;+# endif // !defined(ASIO_NO_DEPRECATED)   typedef typename traits_helper::time_type time_point;   typedef typename traits_helper::duration_type duration; #endif@@ -126,6 +197,7 @@     init_buffers();   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Construct a basic_socket_streambuf from the supplied socket.   explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s)     : detail::socket_streambuf_io_context(0),@@ -169,6 +241,7 @@     other.init_buffers();     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destructor flushes buffered data.   virtual ~basic_socket_streambuf()@@ -192,6 +265,7 @@     return !ec_ ? this : 0;   } +#if defined(GENERATING_DOCUMENTATION)   /// Establish a connection.   /**    * This function automatically establishes a connection based on the supplied@@ -201,6 +275,9 @@    * @return \c this if a connection was successfully established, a null    * pointer otherwise.    */+  template <typename T1, ..., typename TN>+  basic_socket_streambuf* connect(T1 t1, ..., TN tn);+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)   template <typename... T>   basic_socket_streambuf* connect(T... x)   {@@ -210,6 +287,9 @@     connect_to_endpoints(resolver.resolve(x..., ec_));     return !ec_ ? this : 0;   }+#else+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF)+#endif    /// Close the connection.   /**@@ -241,6 +321,30 @@     return ec_;   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use error().) Get the last error associated with the stream+  /// buffer.+  /**+   * @return An \c error_code corresponding to the last error from the stream+   * buffer.+   */+  const asio::error_code& puberror() const+  {+    return error();+  }++  /// (Deprecated: Use expiry().) Get the stream buffer's expiry time as an+  /// absolute time.+  /**+   * @return An absolute time value representing the stream buffer's expiry+   * time.+   */+  time_point expires_at() const+  {+    return expiry_time_;+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Get the stream buffer's expiry time as an absolute time.   /**    * @return An absolute time value representing the stream buffer's expiry@@ -279,6 +383,33 @@     expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use expiry().) Get the stream buffer's expiry time relative+  /// to now.+  /**+   * @return A relative time value representing the stream buffer's expiry time.+   */+  duration expires_from_now() const+  {+    return traits_helper::subtract(expires_at(), traits_helper::now());+  }++  /// (Deprecated: Use expires_after().) Set the stream buffer's expiry time+  /// relative to now.+  /**+   * This function sets the expiry time associated with the stream. Stream+   * operations performed after this time (where the operations cannot be+   * completed using the internal buffers) will fail with the error+   * asio::error::operation_aborted.+   *+   * @param expiry_time The expiry time to be used for the timer.+   */+  void expires_from_now(const duration& expiry_time)+  {+    expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);+  }+#endif // !defined(ASIO_NO_DEPRECATED)+ protected:   int_type underflow()   {@@ -428,9 +559,9 @@  private:   // Disallow copying and assignment.-  basic_socket_streambuf(const basic_socket_streambuf&) = delete;+  basic_socket_streambuf(const basic_socket_streambuf&) ASIO_DELETED;   basic_socket_streambuf& operator=(-      const basic_socket_streambuf&) = delete;+      const basic_socket_streambuf&) ASIO_DELETED;    void init_buffers()   {@@ -528,7 +659,14 @@   // Helper function to get the maximum expiry time.   static time_point max_expiry_time()   {+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+  && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)+    return boost::posix_time::pos_infin;+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+      // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)     return (time_point::max)();+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+       // && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)   }    enum { putback_max = 8 };@@ -539,6 +677,10 @@ } // namespace asio  #include "asio/detail/pop_options.hpp"++#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)+# undef ASIO_PRIVATE_CONNECT_DEF+#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)  #endif // !defined(ASIO_NO_IOSTREAM) 
link/modules/asio-standalone/asio/include/asio/basic_stream_file.hpp view
@@ -2,7 +2,7 @@ // basic_stream_file.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -106,10 +106,10 @@    */   template <typename ExecutionContext>   explicit basic_stream_file(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(context)   {     this->impl_.get_service().set_is_stream(@@ -161,10 +161,10 @@   template <typename ExecutionContext>   basic_stream_file(ExecutionContext& context,       const char* path, file_base::flags open_flags,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(context)   {     asio::error_code ec;@@ -221,10 +221,10 @@   template <typename ExecutionContext>   basic_stream_file(ExecutionContext& context,       const std::string& path, file_base::flags open_flags,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(context)   {     asio::error_code ec;@@ -272,16 +272,17 @@   template <typename ExecutionContext>   basic_stream_file(ExecutionContext& context,       const native_handle_type& native_file,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(context, native_file)   {     this->impl_.get_service().set_is_stream(         this->impl_.get_implementation(), true);   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_stream_file from another.   /**    * This constructor moves a stream file from one object to another.@@ -293,7 +294,7 @@    * constructed using the @c basic_stream_file(const executor_type&)    * constructor.    */-  basic_stream_file(basic_stream_file&& other) noexcept+  basic_stream_file(basic_stream_file&& other) ASIO_NOEXCEPT     : basic_file<Executor>(std::move(other))   {   }@@ -329,10 +330,10 @@    */   template <typename Executor1>   basic_stream_file(basic_stream_file<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_file<Executor>(std::move(other))   {   }@@ -349,14 +350,15 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_stream_file&-  > operator=(basic_stream_file<Executor1>&& other)+  >::type operator=(basic_stream_file<Executor1>&& other)   {     basic_file<Executor>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the file.   /**@@ -490,7 +492,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -520,13 +522,17 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_write_some>(), token, buffers))+          declval<initiate_async_write_some>(), token, buffers)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -618,7 +624,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -649,13 +655,17 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_read_some>(), token, buffers))+          declval<initiate_async_read_some>(), token, buffers)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -664,8 +674,8 @@  private:   // Disallow copying and assignment.-  basic_stream_file(const basic_stream_file&) = delete;-  basic_stream_file& operator=(const basic_stream_file&) = delete;+  basic_stream_file(const basic_stream_file&) ASIO_DELETED;+  basic_stream_file& operator=(const basic_stream_file&) ASIO_DELETED;    class initiate_async_write_some   {@@ -677,13 +687,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler@@ -710,13 +720,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/basic_stream_socket.hpp view
@@ -2,7 +2,7 @@ // basic_stream_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -116,9 +116,9 @@    */   template <typename ExecutionContext>   explicit basic_stream_socket(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context)   {   }@@ -155,10 +155,10 @@    */   template <typename ExecutionContext>   basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_socket<Protocol, Executor>(context, protocol)   {   }@@ -201,9 +201,9 @@    */   template <typename ExecutionContext>   basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context, endpoint)   {   }@@ -246,13 +246,14 @@   template <typename ExecutionContext>   basic_stream_socket(ExecutionContext& context,       const protocol_type& protocol, const native_handle_type& native_socket,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(context, protocol, native_socket)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_stream_socket from another.   /**    * This constructor moves a stream socket from one object to another.@@ -264,7 +265,7 @@    * constructed using the @c basic_stream_socket(const executor_type&)    * constructor.    */-  basic_stream_socket(basic_stream_socket&& other) noexcept+  basic_stream_socket(basic_stream_socket&& other) ASIO_NOEXCEPT     : basic_socket<Protocol, Executor>(std::move(other))   {   }@@ -300,10 +301,10 @@    */   template <typename Protocol1, typename Executor1>   basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Protocol1, Protocol>::value           && is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : basic_socket<Protocol, Executor>(std::move(other))   {   }@@ -320,15 +321,16 @@    * constructor.    */   template <typename Protocol1, typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Protocol1, Protocol>::value       && is_convertible<Executor1, Executor>::value,     basic_stream_socket&-  > operator=(basic_stream_socket<Protocol1, Executor1>&& other)+  >::type operator=(basic_stream_socket<Protocol1, Executor1>&& other)   {     basic_socket<Protocol, Executor>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the socket.   /**@@ -461,7 +463,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -491,14 +493,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_send>(), token,-          buffers, socket_base::message_flags(0)))+          buffers, socket_base::message_flags(0))))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -531,7 +537,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -561,14 +567,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_send(const ConstBufferSequence& buffers,+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_send(const ConstBufferSequence& buffers,       socket_base::message_flags flags,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_send>(), token, buffers, flags))+          declval<initiate_async_send>(), token, buffers, flags)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -703,7 +713,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -735,14 +745,18 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive>(), token,-          buffers, socket_base::message_flags(0)))+          buffers, socket_base::message_flags(0))))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -775,7 +789,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -807,14 +821,18 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_receive(const MutableBufferSequence& buffers,+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_receive(const MutableBufferSequence& buffers,       socket_base::message_flags flags,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_receive>(), token, buffers, flags))+          declval<initiate_async_receive>(), token, buffers, flags)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -905,7 +923,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -935,14 +953,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_send>(), token,-          buffers, socket_base::message_flags(0)))+          buffers, socket_base::message_flags(0))))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -1036,7 +1058,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -1067,14 +1089,18 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(           declval<initiate_async_receive>(), token,-          buffers, socket_base::message_flags(0)))+          buffers, socket_base::message_flags(0))))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -1084,8 +1110,8 @@  private:   // Disallow copying and assignment.-  basic_stream_socket(const basic_stream_socket&) = delete;-  basic_stream_socket& operator=(const basic_stream_socket&) = delete;+  basic_stream_socket(const basic_stream_socket&) ASIO_DELETED;+  basic_stream_socket& operator=(const basic_stream_socket&) ASIO_DELETED;    class initiate_async_send   {@@ -1097,13 +1123,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers,         socket_base::message_flags flags) const     {@@ -1131,13 +1157,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers,         socket_base::message_flags flags) const     {
link/modules/asio-standalone/asio/include/asio/basic_streambuf.hpp view
@@ -2,7 +2,7 @@ // basic_streambuf.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -103,7 +103,7 @@  * @endcode  */ #if defined(GENERATING_DOCUMENTATION)-template <typename Allocator = std::allocator<char>>+template <typename Allocator = std::allocator<char> > #else template <typename Allocator> #endif@@ -119,8 +119,8 @@   /// The type used to represent the output sequence as a list of buffers.   typedef implementation_defined mutable_buffers_type; #else-  typedef const_buffer const_buffers_type;-  typedef mutable_buffer mutable_buffers_type;+  typedef ASIO_CONST_BUFFER const_buffers_type;+  typedef ASIO_MUTABLE_BUFFER mutable_buffers_type; #endif    /// Construct a basic_streambuf object.@@ -155,7 +155,7 @@    * }    * @endcode    */-  std::size_t size() const noexcept+  std::size_t size() const ASIO_NOEXCEPT   {     return pptr() - gptr();   }@@ -165,7 +165,7 @@    * @returns The allowed maximum of the sum of the sizes of the input sequence    * and output sequence.    */-  std::size_t max_size() const noexcept+  std::size_t max_size() const ASIO_NOEXCEPT   {     return max_size_;   }@@ -175,7 +175,7 @@    * @returns The current total capacity of the streambuf, i.e. for both the    * input sequence and output sequence.    */-  std::size_t capacity() const noexcept+  std::size_t capacity() const ASIO_NOEXCEPT   {     return buffer_.capacity();   }@@ -189,7 +189,7 @@    * @note The returned object is invalidated by any @c basic_streambuf member    * function that modifies the input sequence or output sequence.    */-  const_buffers_type data() const noexcept+  const_buffers_type data() const ASIO_NOEXCEPT   {     return asio::buffer(asio::const_buffer(gptr(),           (pptr() - gptr()) * sizeof(char_type)));@@ -361,7 +361,7 @@  /// Adapts basic_streambuf to the dynamic buffer sequence type requirements. #if defined(GENERATING_DOCUMENTATION)-template <typename Allocator = std::allocator<char>>+template <typename Allocator = std::allocator<char> > #else template <typename Allocator> #endif@@ -383,37 +383,39 @@   }    /// Copy construct a basic_streambuf_ref.-  basic_streambuf_ref(const basic_streambuf_ref& other) noexcept+  basic_streambuf_ref(const basic_streambuf_ref& other) ASIO_NOEXCEPT     : sb_(other.sb_)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move construct a basic_streambuf_ref.-  basic_streambuf_ref(basic_streambuf_ref&& other) noexcept+  basic_streambuf_ref(basic_streambuf_ref&& other) ASIO_NOEXCEPT     : sb_(other.sb_)   {   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Get the size of the input sequence.-  std::size_t size() const noexcept+  std::size_t size() const ASIO_NOEXCEPT   {     return sb_.size();   }    /// Get the maximum size of the dynamic buffer.-  std::size_t max_size() const noexcept+  std::size_t max_size() const ASIO_NOEXCEPT   {     return sb_.max_size();   }    /// Get the current capacity of the dynamic buffer.-  std::size_t capacity() const noexcept+  std::size_t capacity() const ASIO_NOEXCEPT   {     return sb_.capacity();   }    /// Get a list of buffers that represents the input sequence.-  const_buffers_type data() const noexcept+  const_buffers_type data() const ASIO_NOEXCEPT   {     return sb_.data();   }
link/modules/asio-standalone/asio/include/asio/basic_streambuf_fwd.hpp view
@@ -2,7 +2,7 @@ // basic_streambuf_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,10 +23,10 @@  namespace asio { -template <typename Allocator = std::allocator<char>>+template <typename Allocator = std::allocator<char> > class basic_streambuf; -template <typename Allocator = std::allocator<char>>+template <typename Allocator = std::allocator<char> > class basic_streambuf_ref;  } // namespace asio
link/modules/asio-standalone/asio/include/asio/basic_waitable_timer.hpp view
@@ -2,7 +2,7 @@ // basic_waitable_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,7 +17,6 @@  #include "asio/detail/config.hpp" #include <cstddef>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/detail/chrono_time_traits.hpp" #include "asio/detail/deadline_timer_service.hpp"@@ -28,6 +27,10 @@ #include "asio/error.hpp" #include "asio/wait_traits.hpp" +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -75,7 +78,7 @@  * timer.wait();  * @endcode  *- * @par+ * @par   * Performing an asynchronous wait (C++11):  * @code  * void handler(const asio::error_code& error)@@ -191,9 +194,9 @@    */   template <typename ExecutionContext>   explicit basic_waitable_timer(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {   }@@ -230,9 +233,9 @@   template <typename ExecutionContext>   explicit basic_waitable_timer(ExecutionContext& context,       const time_point& expiry_time,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -273,9 +276,9 @@   template <typename ExecutionContext>   explicit basic_waitable_timer(ExecutionContext& context,       const duration& expiry_time,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -284,6 +287,7 @@     asio::detail::throw_error(ec, "expires_after");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_waitable_timer from another.   /**    * This constructor moves a timer from one object to another.@@ -336,9 +340,9 @@   template <typename Executor1>   basic_waitable_timer(       basic_waitable_timer<Clock, WaitTraits, Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : impl_(std::move(other.impl_))   {   }@@ -356,15 +360,16 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_waitable_timer&-  > operator=(basic_waitable_timer<Clock, WaitTraits, Executor1>&& other)+  >::type operator=(basic_waitable_timer<Clock, WaitTraits, Executor1>&& other)   {     basic_waitable_timer tmp(std::move(other));     impl_ = std::move(tmp.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the timer.   /**@@ -376,7 +381,7 @@   }    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -411,6 +416,36 @@     return s;   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use non-error_code overload.) Cancel any asynchronous+  /// operations that are waiting on the timer.+  /**+   * This function forces the completion of any pending asynchronous wait+   * operations against the timer. The handler for each cancelled operation will+   * be invoked with the asio::error::operation_aborted error code.+   *+   * Cancelling the timer does not change the expiry time.+   *+   * @param ec Set to indicate what error occurred, if any.+   *+   * @return The number of asynchronous operations that were cancelled.+   *+   * @note If the timer has already expired when cancel() is called, then the+   * handlers for asynchronous wait operations will:+   *+   * @li have already been invoked; or+   *+   * @li have been queued for invocation in the near future.+   *+   * These handlers can no longer be cancelled, and therefore are passed an+   * error code that indicates the successful completion of the wait operation.+   */+  std::size_t cancel(asio::error_code& ec)+  {+    return impl_.get_service().cancel(impl_.get_implementation(), ec);+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Cancels one asynchronous operation that is waiting on the timer.   /**    * This function forces the completion of one pending asynchronous wait@@ -444,6 +479,49 @@     return s;   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use non-error_code overload.) Cancels one asynchronous+  /// operation that is waiting on the timer.+  /**+   * This function forces the completion of one pending asynchronous wait+   * operation against the timer. Handlers are cancelled in FIFO order. The+   * handler for the cancelled operation will be invoked with the+   * asio::error::operation_aborted error code.+   *+   * Cancelling the timer does not change the expiry time.+   *+   * @param ec Set to indicate what error occurred, if any.+   *+   * @return The number of asynchronous operations that were cancelled. That is,+   * either 0 or 1.+   *+   * @note If the timer has already expired when cancel_one() is called, then+   * the handlers for asynchronous wait operations will:+   *+   * @li have already been invoked; or+   *+   * @li have been queued for invocation in the near future.+   *+   * These handlers can no longer be cancelled, and therefore are passed an+   * error code that indicates the successful completion of the wait operation.+   */+  std::size_t cancel_one(asio::error_code& ec)+  {+    return impl_.get_service().cancel_one(impl_.get_implementation(), ec);+  }++  /// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute+  /// time.+  /**+   * This function may be used to obtain the timer's current expiry time.+   * Whether the timer has expired or not does not affect this value.+   */+  time_point expires_at() const+  {+    return impl_.get_service().expires_at(impl_.get_implementation());+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Get the timer's expiry time as an absolute time.   /**    * This function may be used to obtain the timer's current expiry time.@@ -485,6 +563,38 @@     return s;   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use non-error_code overload.) Set the timer's expiry time as+  /// an absolute time.+  /**+   * This function sets the expiry time. Any pending asynchronous wait+   * operations will be cancelled. The handler for each cancelled operation will+   * be invoked with the asio::error::operation_aborted error code.+   *+   * @param expiry_time The expiry time to be used for the timer.+   *+   * @param ec Set to indicate what error occurred, if any.+   *+   * @return The number of asynchronous operations that were cancelled.+   *+   * @note If the timer has already expired when expires_at() is called, then+   * the handlers for asynchronous wait operations will:+   *+   * @li have already been invoked; or+   *+   * @li have been queued for invocation in the near future.+   *+   * These handlers can no longer be cancelled, and therefore are passed an+   * error code that indicates the successful completion of the wait operation.+   */+  std::size_t expires_at(const time_point& expiry_time,+      asio::error_code& ec)+  {+    return impl_.get_service().expires_at(+        impl_.get_implementation(), expiry_time, ec);+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Set the timer's expiry time relative to now.   /**    * This function sets the expiry time. Any pending asynchronous wait@@ -516,6 +626,80 @@     return s;   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use expiry().) Get the timer's expiry time relative to now.+  /**+   * This function may be used to obtain the timer's current expiry time.+   * Whether the timer has expired or not does not affect this value.+   */+  duration expires_from_now() const+  {+    return impl_.get_service().expires_from_now(impl_.get_implementation());+  }++  /// (Deprecated: Use expires_after().) Set the timer's expiry time relative+  /// to now.+  /**+   * This function sets the expiry time. Any pending asynchronous wait+   * operations will be cancelled. The handler for each cancelled operation will+   * be invoked with the asio::error::operation_aborted error code.+   *+   * @param expiry_time The expiry time to be used for the timer.+   *+   * @return The number of asynchronous operations that were cancelled.+   *+   * @throws asio::system_error Thrown on failure.+   *+   * @note If the timer has already expired when expires_from_now() is called,+   * then the handlers for asynchronous wait operations will:+   *+   * @li have already been invoked; or+   *+   * @li have been queued for invocation in the near future.+   *+   * These handlers can no longer be cancelled, and therefore are passed an+   * error code that indicates the successful completion of the wait operation.+   */+  std::size_t expires_from_now(const duration& expiry_time)+  {+    asio::error_code ec;+    std::size_t s = impl_.get_service().expires_from_now(+        impl_.get_implementation(), expiry_time, ec);+    asio::detail::throw_error(ec, "expires_from_now");+    return s;+  }++  /// (Deprecated: Use expires_after().) Set the timer's expiry time relative+  /// to now.+  /**+   * This function sets the expiry time. Any pending asynchronous wait+   * operations will be cancelled. The handler for each cancelled operation will+   * be invoked with the asio::error::operation_aborted error code.+   *+   * @param expiry_time The expiry time to be used for the timer.+   *+   * @param ec Set to indicate what error occurred, if any.+   *+   * @return The number of asynchronous operations that were cancelled.+   *+   * @note If the timer has already expired when expires_from_now() is called,+   * then the handlers for asynchronous wait operations will:+   *+   * @li have already been invoked; or+   *+   * @li have been queued for invocation in the near future.+   *+   * These handlers can no longer be cancelled, and therefore are passed an+   * error code that indicates the successful completion of the wait operation.+   */+  std::size_t expires_from_now(const duration& expiry_time,+      asio::error_code& ec)+  {+    return impl_.get_service().expires_from_now(+        impl_.get_implementation(), expiry_time, ec);+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Perform a blocking wait on the timer.   /**    * This function is used to wait for the timer to expire. This function@@ -567,7 +751,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -584,12 +768,15 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        WaitToken = default_completion_token_t<executor_type>>-  auto async_wait(-      WaitToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(+      WaitToken, void (asio::error_code))+  async_wait(+      ASIO_MOVE_ARG(WaitToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WaitToken, void (asio::error_code)>(-        declval<initiate_async_wait>(), token))+          declval<initiate_async_wait>(), token)))   {     return async_initiate<WaitToken, void (asio::error_code)>(         initiate_async_wait(this), token);@@ -597,8 +784,9 @@  private:   // Disallow copying and assignment.-  basic_waitable_timer(const basic_waitable_timer&) = delete;-  basic_waitable_timer& operator=(const basic_waitable_timer&) = delete;+  basic_waitable_timer(const basic_waitable_timer&) ASIO_DELETED;+  basic_waitable_timer& operator=(+      const basic_waitable_timer&) ASIO_DELETED;    class initiate_async_wait   {@@ -610,13 +798,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WaitHandler>-    void operator()(WaitHandler&& handler) const+    void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WaitHandler.@@ -634,7 +822,7 @@    detail::io_object_impl<     detail::deadline_timer_service<-      detail::chrono_time_traits<Clock, WaitTraits>>,+      detail::chrono_time_traits<Clock, WaitTraits> >,     executor_type > impl_; }; 
link/modules/asio-standalone/asio/include/asio/basic_writable_pipe.hpp view
@@ -2,7 +2,7 @@ // basic_writable_pipe.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,7 +21,6 @@   || defined(GENERATING_DOCUMENTATION)  #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -39,6 +38,10 @@ # include "asio/detail/reactive_descriptor_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -109,10 +112,10 @@    */   template <typename ExecutionContext>   explicit basic_writable_pipe(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {   }@@ -156,9 +159,9 @@   template <typename ExecutionContext>   basic_writable_pipe(ExecutionContext& context,       const native_handle_type& native_pipe,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -167,6 +170,7 @@     asio::detail::throw_error(ec, "assign");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_writable_pipe from another.   /**    * This constructor moves a pipe from one object to another.@@ -217,10 +221,10 @@    */   template <typename Executor1>   basic_writable_pipe(basic_writable_pipe<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(std::move(other.impl_))   {   }@@ -237,15 +241,16 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_writable_pipe&-  > operator=(basic_writable_pipe<Executor1>&& other)+  >::type operator=(basic_writable_pipe<Executor1>&& other)   {     basic_writable_pipe tmp(std::move(other));     impl_ = std::move(tmp.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the pipe.   /**@@ -258,7 +263,7 @@   }    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -532,7 +537,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -552,13 +557,17 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_write_some>(), token, buffers))+          declval<initiate_async_write_some>(), token, buffers)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -567,8 +576,8 @@  private:   // Disallow copying and assignment.-  basic_writable_pipe(const basic_writable_pipe&) = delete;-  basic_writable_pipe& operator=(const basic_writable_pipe&) = delete;+  basic_writable_pipe(const basic_writable_pipe&) ASIO_DELETED;+  basic_writable_pipe& operator=(const basic_writable_pipe&) ASIO_DELETED;    class initiate_async_write_some   {@@ -580,13 +589,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/bind_allocator.hpp view
@@ -2,7 +2,7 @@ // bind_allocator.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,12 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/associated_allocator.hpp"-#include "asio/associated_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/type_traits.hpp"  #include "asio/detail/push_options.hpp" @@ -38,7 +37,8 @@ };  template <typename T>-struct allocator_binder_result_type<T, void_t<typename T::result_type>>+struct allocator_binder_result_type<T,+  typename void_type<typename T::result_type>::type> {   typedef typename T::result_type result_type; protected:@@ -99,7 +99,8 @@ struct allocator_binder_argument_type {};  template <typename T>-struct allocator_binder_argument_type<T, void_t<typename T::argument_type>>+struct allocator_binder_argument_type<T,+  typename void_type<typename T::argument_type>::type> {   typedef typename T::argument_type argument_type; };@@ -124,7 +125,7 @@  template <typename T> struct allocator_binder_argument_types<T,-    void_t<typename T::first_argument_type>>+  typename void_type<typename T::first_argument_type>::type> {   typedef typename T::first_argument_type first_argument_type;   typedef typename T::second_argument_type second_argument_type;@@ -144,6 +145,21 @@   typedef A2 second_argument_type; }; +// Helper to enable SFINAE on zero-argument operator() below.++template <typename T, typename = void>+struct allocator_binder_result_of0+{+  typedef void type;+};++template <typename T>+struct allocator_binder_result_of0<T,+  typename void_type<typename result_of<T()>::type>::type>+{+  typedef typename result_of<T()>::type type;+};+ } // namespace detail  /// A call wrapper type to bind an allocator of type @c Allocator@@ -231,9 +247,10 @@    * @c U.    */   template <typename U>-  allocator_binder(const allocator_type& s, U&& u)+  allocator_binder(const allocator_type& s,+      ASIO_MOVE_ARG(U) u)     : allocator_(s),-      target_(static_cast<U&&>(u))+      target_(ASIO_MOVE_CAST(U)(u))   {   } @@ -245,7 +262,8 @@   }    /// Construct a copy, but specify a different allocator.-  allocator_binder(const allocator_type& s, const allocator_binder& other)+  allocator_binder(const allocator_type& s,+      const allocator_binder& other)     : allocator_(s),       target_(other.get())   {@@ -258,9 +276,8 @@    * constructible from type @c U.    */   template <typename U, typename OtherAllocator>-  allocator_binder(const allocator_binder<U, OtherAllocator>& other,-      constraint_t<is_constructible<Allocator, OtherAllocator>::value> = 0,-      constraint_t<is_constructible<T, U>::value> = 0)+  allocator_binder(+      const allocator_binder<U, OtherAllocator>& other)     : allocator_(other.get_allocator()),       target_(other.get())   {@@ -274,18 +291,19 @@    */   template <typename U, typename OtherAllocator>   allocator_binder(const allocator_type& s,-      const allocator_binder<U, OtherAllocator>& other,-      constraint_t<is_constructible<T, U>::value> = 0)+      const allocator_binder<U, OtherAllocator>& other)     : allocator_(s),       target_(other.get())   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+   /// Move constructor.   allocator_binder(allocator_binder&& other)-    : allocator_(static_cast<allocator_type&&>(+    : allocator_(ASIO_MOVE_CAST(allocator_type)(           other.get_allocator())),-      target_(static_cast<T&&>(other.get()))+      target_(ASIO_MOVE_CAST(T)(other.get()))   {   } @@ -293,19 +311,17 @@   allocator_binder(const allocator_type& s,       allocator_binder&& other)     : allocator_(s),-      target_(static_cast<T&&>(other.get()))+      target_(ASIO_MOVE_CAST(T)(other.get()))   {   }    /// Move construct from a different allocator wrapper type.   template <typename U, typename OtherAllocator>   allocator_binder(-      allocator_binder<U, OtherAllocator>&& other,-      constraint_t<is_constructible<Allocator, OtherAllocator>::value> = 0,-      constraint_t<is_constructible<T, U>::value> = 0)-    : allocator_(static_cast<OtherAllocator&&>(+      allocator_binder<U, OtherAllocator>&& other)+    : allocator_(ASIO_MOVE_CAST(OtherAllocator)(           other.get_allocator())),-      target_(static_cast<U&&>(other.get()))+      target_(ASIO_MOVE_CAST(U)(other.get()))   {   } @@ -313,148 +329,162 @@   /// specify a different allocator.   template <typename U, typename OtherAllocator>   allocator_binder(const allocator_type& s,-      allocator_binder<U, OtherAllocator>&& other,-      constraint_t<is_constructible<T, U>::value> = 0)+      allocator_binder<U, OtherAllocator>&& other)     : allocator_(s),-      target_(static_cast<U&&>(other.get()))+      target_(ASIO_MOVE_CAST(U)(other.get()))   {   } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+   /// Destructor.   ~allocator_binder()   {   }    /// Obtain a reference to the target object.-  target_type& get() noexcept+  target_type& get() ASIO_NOEXCEPT   {     return target_;   }    /// Obtain a reference to the target object.-  const target_type& get() const noexcept+  const target_type& get() const ASIO_NOEXCEPT   {     return target_;   }    /// Obtain the associated allocator.-  allocator_type get_allocator() const noexcept+  allocator_type get_allocator() const ASIO_NOEXCEPT   {     return allocator_;   } +#if defined(GENERATING_DOCUMENTATION)++  template <typename... Args> auto operator()(Args&& ...);+  template <typename... Args> auto operator()(Args&& ...) const;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)+   /// Forwarding function call operator.   template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) &+  typename result_of<T(Args...)>::type operator()(+      ASIO_MOVE_ARG(Args)... args)   {-    return target_(static_cast<Args&&>(args)...);+    return target_(ASIO_MOVE_CAST(Args)(args)...);   }    /// Forwarding function call operator.   template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) &&+  typename result_of<T(Args...)>::type operator()(+      ASIO_MOVE_ARG(Args)... args) const   {-    return static_cast<T&&>(target_)(static_cast<Args&&>(args)...);+    return target_(ASIO_MOVE_CAST(Args)(args)...);   } -  /// Forwarding function call operator.-  template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) const&+#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++  typename detail::allocator_binder_result_of0<T>::type operator()()   {-    return target_(static_cast<Args&&>(args)...);+    return target_();   } -private:-  Allocator allocator_;-  T target_;-};+  typename detail::allocator_binder_result_of0<T>::type+  operator()() const+  {+    return target_();+  } -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler should have the supplied allocator as its associated-/// allocator.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Allocator>-struct partial_allocator_binder-{-  /// Constructor that specifies associated allocator.-  explicit partial_allocator_binder(const Allocator& ex)-    : allocator_(ex)+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) const \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++  typedef typename detail::allocator_binder_result_type<+    T>::result_type_or_void result_type_or_void;++  result_type_or_void operator()()   {+    return target_();   } -  /// Adapt a @ref completion_token to specify that the completion handler-  /// should have the allocator as its associated allocator.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  constexpr allocator_binder<decay_t<CompletionToken>, Allocator>-  operator()(CompletionToken&& completion_token) const+  result_type_or_void operator()() const   {-    return allocator_binder<decay_t<CompletionToken>, Allocator>(-        allocator_, static_cast<CompletionToken&&>(completion_token));+    return target_();   } -//private:+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  result_type_or_void operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  result_type_or_void operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) const \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++private:   Allocator allocator_;+  T target_; }; -/// Create a partial completion token that associates an allocator.-template <typename Allocator>-ASIO_NODISCARD inline partial_allocator_binder<Allocator>-bind_allocator(const Allocator& ex)-{-  return partial_allocator_binder<Allocator>(ex);-}- /// Associate an object of type @c T with an allocator of type /// @c Allocator. template <typename Allocator, typename T>-ASIO_NODISCARD inline allocator_binder<decay_t<T>, Allocator>-bind_allocator(const Allocator& s, T&& t)+ASIO_NODISCARD inline allocator_binder<typename decay<T>::type, Allocator>+bind_allocator(const Allocator& s, ASIO_MOVE_ARG(T) t) {-  return allocator_binder<decay_t<T>, Allocator>(s, static_cast<T&&>(t));+  return allocator_binder<+    typename decay<T>::type, Allocator>(+      s, ASIO_MOVE_CAST(T)(t)); }  #if !defined(GENERATING_DOCUMENTATION)  namespace detail { -template <typename TargetAsyncResult, typename Allocator, typename = void>-class allocator_binder_completion_handler_async_result+template <typename TargetAsyncResult,+  typename Allocator, typename = void>+struct allocator_binder_async_result_completion_handler_type {-public:-  template <typename T>-  explicit allocator_binder_completion_handler_async_result(T&)-  {-  } };  template <typename TargetAsyncResult, typename Allocator>-class allocator_binder_completion_handler_async_result<-    TargetAsyncResult, Allocator,-    void_t<typename TargetAsyncResult::completion_handler_type>>+struct allocator_binder_async_result_completion_handler_type<+  TargetAsyncResult, Allocator,+  typename void_type<+    typename TargetAsyncResult::completion_handler_type+  >::type> {-private:-  TargetAsyncResult target_;--public:   typedef allocator_binder<     typename TargetAsyncResult::completion_handler_type, Allocator>       completion_handler_type;--  explicit allocator_binder_completion_handler_async_result(-      typename TargetAsyncResult::completion_handler_type& handler)-    : target_(handler)-  {-  }--  auto get() -> decltype(target_.get())-  {-    return target_.get();-  } };  template <typename TargetAsyncResult, typename = void>@@ -464,7 +494,10 @@  template <typename TargetAsyncResult> struct allocator_binder_async_result_return_type<-    TargetAsyncResult, void_type<typename TargetAsyncResult::return_type>>+  TargetAsyncResult,+  typename void_type<+    typename TargetAsyncResult::return_type+  >::type> {   typedef typename TargetAsyncResult::return_type return_type; };@@ -473,122 +506,219 @@  template <typename T, typename Allocator, typename Signature> class async_result<allocator_binder<T, Allocator>, Signature> :-  public detail::allocator_binder_completion_handler_async_result<-      async_result<T, Signature>, Allocator>,+  public detail::allocator_binder_async_result_completion_handler_type<+    async_result<T, Signature>, Allocator>,   public detail::allocator_binder_async_result_return_type<-      async_result<T, Signature>>+    async_result<T, Signature> > { public:   explicit async_result(allocator_binder<T, Allocator>& b)-    : detail::allocator_binder_completion_handler_async_result<-        async_result<T, Signature>, Allocator>(b.get())+    : target_(b.get())   {   } +  typename async_result<T, Signature>::return_type get()+  {+    return target_.get();+  }+   template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;+    template <typename Init>+    init_wrapper(const Allocator& allocator, ASIO_MOVE_ARG(Init) init)+      : allocator_(allocator),+        initiation_(ASIO_MOVE_CAST(Init)(init))+    {+    } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+     template <typename Handler, typename... Args>-    void operator()(Handler&& handler, const Allocator& a, Args&&... args) &&+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<Initiation&&>(*this)(-          allocator_binder<decay_t<Handler>, Allocator>(-              a, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          allocator_binder<+            typename decay<Handler>::type, Allocator>(+              allocator_, ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        const Allocator& a, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args) const     {-      static_cast<const Initiation&>(*this)(-          allocator_binder<decay_t<Handler>, Allocator>(-              a, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      initiation_(+          allocator_binder<+            typename decay<Handler>::type, Allocator>(+              allocator_, ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    template <typename Handler>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler)+    {+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          allocator_binder<+            typename decay<Handler>::type, Allocator>(+              allocator_, ASIO_MOVE_CAST(Handler)(handler)));+    }++    template <typename Handler>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler) const+    {+      initiation_(+          allocator_binder<+            typename decay<Handler>::type, Allocator>(+              allocator_, ASIO_MOVE_CAST(Handler)(handler)));+    }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+    template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+    void operator()( \+        ASIO_MOVE_ARG(Handler) handler, \+        ASIO_VARIADIC_MOVE_PARAMS(n)) \+    { \+      ASIO_MOVE_CAST(Initiation)(initiation_)( \+          allocator_binder< \+            typename decay<Handler>::type, Allocator>( \+              allocator_, ASIO_MOVE_CAST(Handler)(handler)), \+          ASIO_VARIADIC_MOVE_ARGS(n)); \+    } \+    \+    template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+    void operator()( \+        ASIO_MOVE_ARG(Handler) handler, \+        ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    { \+      initiation_( \+          allocator_binder< \+            typename decay<Handler>::type, Allocator>( \+              allocator_, ASIO_MOVE_CAST(Handler)(handler)), \+          ASIO_VARIADIC_MOVE_ARGS(n)); \+    } \+    /**/+    ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    Allocator allocator_;+    Initiation initiation_;   }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,-        Signature>(-        declval<init_wrapper<decay_t<Initiation>>>(),-        token.get(), token.get_allocator(), static_cast<Args&&>(args)...))+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+    (async_initiate<T, Signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<RawCompletionToken>().get(),+        declval<ASIO_MOVE_ARG(Args)>()...)))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)   {-    return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,-      Signature>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.get(), token.get_allocator(), static_cast<Args&&>(args)...);+    return async_initiate<T, Signature>(+        init_wrapper<typename decay<Initiation>::type>(+          token.get_allocator(),+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.get(), ASIO_MOVE_CAST(Args)(args)...);   } -private:-  async_result(const async_result&) = delete;-  async_result& operator=(const async_result&) = delete;--  async_result<T, Signature> target_;-};+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename Allocator, typename... Signatures>-struct async_result<partial_allocator_binder<Allocator>, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        allocator_binder<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Allocator>(token.allocator_,-            default_completion_token_t<associated_executor_t<Initiation>>{}),-        static_cast<Args&&>(args)...))+  template <typename Initiation, typename RawCompletionToken>+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+    (async_initiate<T, Signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<RawCompletionToken>().get())))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token)   {-    return async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        allocator_binder<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Allocator>(token.allocator_,-            default_completion_token_t<associated_executor_t<Initiation>>{}),-        static_cast<Args&&>(args)...);+    return async_initiate<T, Signature>(+        init_wrapper<typename decay<Initiation>::type>(+          token.get_allocator(),+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.get());   }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, typename RawCompletionToken, \+      ASIO_VARIADIC_TPARAMS(n)> \+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \+    (async_initiate<T, Signature>( \+        declval<init_wrapper<typename decay<Initiation>::type> >(), \+        declval<RawCompletionToken>().get(), \+        ASIO_VARIADIC_MOVE_DECLVAL(n)))) \+  initiate( \+      ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_MOVE_ARG(RawCompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return async_initiate<T, Signature>( \+        init_wrapper<typename decay<Initiation>::type>( \+          token.get_allocator(), \+          ASIO_MOVE_CAST(Initiation)(initiation)), \+        token.get(), ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+  async_result(const async_result&) ASIO_DELETED;+  async_result& operator=(const async_result&) ASIO_DELETED;++  async_result<T, Signature> target_; };  template <template <typename, typename> class Associator,     typename T, typename Allocator, typename DefaultCandidate>-struct associator<Associator, allocator_binder<T, Allocator>, DefaultCandidate>+struct associator<Associator,+    allocator_binder<T, Allocator>,+    DefaultCandidate>   : Associator<T, DefaultCandidate> {-  static typename Associator<T, DefaultCandidate>::type get(-      const allocator_binder<T, Allocator>& b) noexcept+  static typename Associator<T, DefaultCandidate>::type+  get(const allocator_binder<T, Allocator>& b) ASIO_NOEXCEPT   {     return Associator<T, DefaultCandidate>::get(b.get());   } -  static auto get(const allocator_binder<T, Allocator>& b,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<T, DefaultCandidate>::type)+  get(const allocator_binder<T, Allocator>& b,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<T, DefaultCandidate>::get(b.get(), c)))   {     return Associator<T, DefaultCandidate>::get(b.get(), c);   } };  template <typename T, typename Allocator, typename Allocator1>-struct associated_allocator<allocator_binder<T, Allocator>, Allocator1>+struct associated_allocator<+    allocator_binder<T, Allocator>,+    Allocator1> {   typedef Allocator type; -  static auto get(const allocator_binder<T, Allocator>& b,-      const Allocator1& = Allocator1()) noexcept-    -> decltype(b.get_allocator())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const allocator_binder<T, Allocator>& b,+      const Allocator1& = Allocator1()) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((b.get_allocator()))   {     return b.get_allocator();   }
link/modules/asio-standalone/asio/include/asio/bind_cancellation_slot.hpp view
@@ -2,7 +2,7 @@ // bind_cancellation_slot.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,12 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/associated_cancellation_slot.hpp"-#include "asio/associated_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/type_traits.hpp"  #include "asio/detail/push_options.hpp" @@ -38,7 +37,8 @@ };  template <typename T>-struct cancellation_slot_binder_result_type<T, void_t<typename T::result_type>>+struct cancellation_slot_binder_result_type<T,+  typename void_type<typename T::result_type>::type> {   typedef typename T::result_type result_type; protected:@@ -100,7 +100,7 @@  template <typename T> struct cancellation_slot_binder_argument_type<T,-    void_t<typename T::argument_type>>+  typename void_type<typename T::argument_type>::type> {   typedef typename T::argument_type argument_type; };@@ -125,7 +125,7 @@  template <typename T> struct cancellation_slot_binder_argument_types<T,-    void_t<typename T::first_argument_type>>+  typename void_type<typename T::first_argument_type>::type> {   typedef typename T::first_argument_type first_argument_type;   typedef typename T::second_argument_type second_argument_type;@@ -145,6 +145,21 @@   typedef A2 second_argument_type; }; +// Helper to enable SFINAE on zero-argument operator() below.++template <typename T, typename = void>+struct cancellation_slot_binder_result_of0+{+  typedef void type;+};++template <typename T>+struct cancellation_slot_binder_result_of0<T,+  typename void_type<typename result_of<T()>::type>::type>+{+  typedef typename result_of<T()>::type type;+};+ } // namespace detail  /// A call wrapper type to bind a cancellation slot of type @c CancellationSlot@@ -232,9 +247,10 @@    * @c U.    */   template <typename U>-  cancellation_slot_binder(const cancellation_slot_type& s, U&& u)+  cancellation_slot_binder(const cancellation_slot_type& s,+      ASIO_MOVE_ARG(U) u)     : slot_(s),-      target_(static_cast<U&&>(u))+      target_(ASIO_MOVE_CAST(U)(u))   {   } @@ -261,10 +277,7 @@    */   template <typename U, typename OtherCancellationSlot>   cancellation_slot_binder(-      const cancellation_slot_binder<U, OtherCancellationSlot>& other,-      constraint_t<is_constructible<CancellationSlot,-        OtherCancellationSlot>::value> = 0,-      constraint_t<is_constructible<T, U>::value> = 0)+      const cancellation_slot_binder<U, OtherCancellationSlot>& other)     : slot_(other.get_cancellation_slot()),       target_(other.get())   {@@ -278,18 +291,19 @@    */   template <typename U, typename OtherCancellationSlot>   cancellation_slot_binder(const cancellation_slot_type& s,-      const cancellation_slot_binder<U, OtherCancellationSlot>& other,-      constraint_t<is_constructible<T, U>::value> = 0)+      const cancellation_slot_binder<U, OtherCancellationSlot>& other)     : slot_(s),       target_(other.get())   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+   /// Move constructor.   cancellation_slot_binder(cancellation_slot_binder&& other)-    : slot_(static_cast<cancellation_slot_type&&>(+    : slot_(ASIO_MOVE_CAST(cancellation_slot_type)(           other.get_cancellation_slot())),-      target_(static_cast<T&&>(other.get()))+      target_(ASIO_MOVE_CAST(T)(other.get()))   {   } @@ -298,20 +312,17 @@   cancellation_slot_binder(const cancellation_slot_type& s,       cancellation_slot_binder&& other)     : slot_(s),-      target_(static_cast<T&&>(other.get()))+      target_(ASIO_MOVE_CAST(T)(other.get()))   {   }    /// Move construct from a different cancellation slot wrapper type.   template <typename U, typename OtherCancellationSlot>   cancellation_slot_binder(-      cancellation_slot_binder<U, OtherCancellationSlot>&& other,-      constraint_t<is_constructible<CancellationSlot,-        OtherCancellationSlot>::value> = 0,-      constraint_t<is_constructible<T, U>::value> = 0)-    : slot_(static_cast<OtherCancellationSlot&&>(+      cancellation_slot_binder<U, OtherCancellationSlot>&& other)+    : slot_(ASIO_MOVE_CAST(OtherCancellationSlot)(           other.get_cancellation_slot())),-      target_(static_cast<U&&>(other.get()))+      target_(ASIO_MOVE_CAST(U)(other.get()))   {   } @@ -319,111 +330,141 @@   /// specify a different cancellation slot.   template <typename U, typename OtherCancellationSlot>   cancellation_slot_binder(const cancellation_slot_type& s,-      cancellation_slot_binder<U, OtherCancellationSlot>&& other,-      constraint_t<is_constructible<T, U>::value> = 0)+      cancellation_slot_binder<U, OtherCancellationSlot>&& other)     : slot_(s),-      target_(static_cast<U&&>(other.get()))+      target_(ASIO_MOVE_CAST(U)(other.get()))   {   } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+   /// Destructor.   ~cancellation_slot_binder()   {   }    /// Obtain a reference to the target object.-  target_type& get() noexcept+  target_type& get() ASIO_NOEXCEPT   {     return target_;   }    /// Obtain a reference to the target object.-  const target_type& get() const noexcept+  const target_type& get() const ASIO_NOEXCEPT   {     return target_;   }    /// Obtain the associated cancellation slot.-  cancellation_slot_type get_cancellation_slot() const noexcept+  cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT   {     return slot_;   } +#if defined(GENERATING_DOCUMENTATION)++  template <typename... Args> auto operator()(Args&& ...);+  template <typename... Args> auto operator()(Args&& ...) const;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)+   /// Forwarding function call operator.   template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) &+  typename result_of<T(Args...)>::type operator()(+      ASIO_MOVE_ARG(Args)... args)   {-    return target_(static_cast<Args&&>(args)...);+    return target_(ASIO_MOVE_CAST(Args)(args)...);   }    /// Forwarding function call operator.   template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) &&+  typename result_of<T(Args...)>::type operator()(+      ASIO_MOVE_ARG(Args)... args) const   {-    return static_cast<T&&>(target_)(static_cast<Args&&>(args)...);+    return target_(ASIO_MOVE_CAST(Args)(args)...);   } -  /// Forwarding function call operator.-  template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) const&+#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++  typename detail::cancellation_slot_binder_result_of0<T>::type operator()()   {-    return target_(static_cast<Args&&>(args)...);+    return target_();   } -private:-  CancellationSlot slot_;-  T target_;-};+  typename detail::cancellation_slot_binder_result_of0<T>::type+  operator()() const+  {+    return target_();+  } -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler should have the supplied cancellation slot as its-/// associated cancellation slot.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename CancellationSlot>-struct partial_cancellation_slot_binder-{-  /// Constructor that specifies associated cancellation slot.-  explicit partial_cancellation_slot_binder(const CancellationSlot& ex)-    : cancellation_slot_(ex)+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) const \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++  typedef typename detail::cancellation_slot_binder_result_type<+    T>::result_type_or_void result_type_or_void;++  result_type_or_void operator()()   {+    return target_();   } -  /// Adapt a @ref completion_token to specify that the completion handler-  /// should have the cancellation slot as its associated cancellation slot.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  constexpr cancellation_slot_binder<decay_t<CompletionToken>, CancellationSlot>-  operator()(CompletionToken&& completion_token) const+  result_type_or_void operator()() const   {-    return cancellation_slot_binder<decay_t<CompletionToken>, CancellationSlot>(-        static_cast<CompletionToken&&>(completion_token), cancellation_slot_);+    return target_();   } -//private:-  CancellationSlot cancellation_slot_;-};+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  result_type_or_void operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  result_type_or_void operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) const \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF -/// Create a partial completion token that associates a cancellation slot.-template <typename CancellationSlot>-ASIO_NODISCARD inline partial_cancellation_slot_binder<CancellationSlot>-bind_cancellation_slot(const CancellationSlot& ex)-{-  return partial_cancellation_slot_binder<CancellationSlot>(ex);-}+#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) +private:+  CancellationSlot slot_;+  T target_;+};+ /// Associate an object of type @c T with a cancellation slot of type /// @c CancellationSlot. template <typename CancellationSlot, typename T> ASIO_NODISCARD inline-cancellation_slot_binder<decay_t<T>, CancellationSlot>-bind_cancellation_slot(const CancellationSlot& s, T&& t)+cancellation_slot_binder<typename decay<T>::type, CancellationSlot>+bind_cancellation_slot(const CancellationSlot& s, ASIO_MOVE_ARG(T) t) {-  return cancellation_slot_binder<decay_t<T>, CancellationSlot>(-      s, static_cast<T&&>(t));+  return cancellation_slot_binder<+    typename decay<T>::type, CancellationSlot>(+      s, ASIO_MOVE_CAST(T)(t)); }  #if !defined(GENERATING_DOCUMENTATION)@@ -431,39 +472,21 @@ namespace detail {  template <typename TargetAsyncResult,-    typename CancellationSlot, typename = void>-class cancellation_slot_binder_completion_handler_async_result+  typename CancellationSlot, typename = void>+struct cancellation_slot_binder_async_result_completion_handler_type {-public:-  template <typename T>-  explicit cancellation_slot_binder_completion_handler_async_result(T&)-  {-  } };  template <typename TargetAsyncResult, typename CancellationSlot>-class cancellation_slot_binder_completion_handler_async_result<-    TargetAsyncResult, CancellationSlot,-    void_t<typename TargetAsyncResult::completion_handler_type>>+struct cancellation_slot_binder_async_result_completion_handler_type<+  TargetAsyncResult, CancellationSlot,+  typename void_type<+    typename TargetAsyncResult::completion_handler_type+  >::type> {-private:-  TargetAsyncResult target_;--public:   typedef cancellation_slot_binder<     typename TargetAsyncResult::completion_handler_type, CancellationSlot>       completion_handler_type;--  explicit cancellation_slot_binder_completion_handler_async_result(-      typename TargetAsyncResult::completion_handler_type& handler)-    : target_(handler)-  {-  }--  auto get() -> decltype(target_.get())-  {-    return target_.get();-  } };  template <typename TargetAsyncResult, typename = void>@@ -473,7 +496,10 @@  template <typename TargetAsyncResult> struct cancellation_slot_binder_async_result_return_type<-    TargetAsyncResult, void_t<typename TargetAsyncResult::return_type>>+  TargetAsyncResult,+  typename void_type<+    typename TargetAsyncResult::return_type+  >::type> {   typedef typename TargetAsyncResult::return_type return_type; };@@ -482,97 +508,182 @@  template <typename T, typename CancellationSlot, typename Signature> class async_result<cancellation_slot_binder<T, CancellationSlot>, Signature> :-  public detail::cancellation_slot_binder_completion_handler_async_result<-      async_result<T, Signature>, CancellationSlot>,+  public detail::cancellation_slot_binder_async_result_completion_handler_type<+    async_result<T, Signature>, CancellationSlot>,   public detail::cancellation_slot_binder_async_result_return_type<-      async_result<T, Signature>>+    async_result<T, Signature> > { public:   explicit async_result(cancellation_slot_binder<T, CancellationSlot>& b)-    : detail::cancellation_slot_binder_completion_handler_async_result<-        async_result<T, Signature>, CancellationSlot>(b.get())+    : target_(b.get())   {   } +  typename async_result<T, Signature>::return_type get()+  {+    return target_.get();+  }+   template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;+    template <typename Init>+    init_wrapper(const CancellationSlot& slot, ASIO_MOVE_ARG(Init) init)+      : slot_(slot),+        initiation_(ASIO_MOVE_CAST(Init)(init))+    {+    } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+     template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        const CancellationSlot& slot, Args&&... args) &&+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<Initiation&&>(*this)(-          cancellation_slot_binder<decay_t<Handler>, CancellationSlot>(-              slot, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          cancellation_slot_binder<+            typename decay<Handler>::type, CancellationSlot>(+              slot_, ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        const CancellationSlot& slot, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args) const     {-      static_cast<const Initiation&>(*this)(-          cancellation_slot_binder<decay_t<Handler>, CancellationSlot>(-              slot, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      initiation_(+          cancellation_slot_binder<+            typename decay<Handler>::type, CancellationSlot>(+              slot_, ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    template <typename Handler>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler)+    {+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          cancellation_slot_binder<+            typename decay<Handler>::type, CancellationSlot>(+              slot_, ASIO_MOVE_CAST(Handler)(handler)));+    }++    template <typename Handler>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler) const+    {+      initiation_(+          cancellation_slot_binder<+            typename decay<Handler>::type, CancellationSlot>(+              slot_, ASIO_MOVE_CAST(Handler)(handler)));+    }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+    template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+    void operator()( \+        ASIO_MOVE_ARG(Handler) handler, \+        ASIO_VARIADIC_MOVE_PARAMS(n)) \+    { \+      ASIO_MOVE_CAST(Initiation)(initiation_)( \+          cancellation_slot_binder< \+            typename decay<Handler>::type, CancellationSlot>( \+              slot_, ASIO_MOVE_CAST(Handler)(handler)), \+          ASIO_VARIADIC_MOVE_ARGS(n)); \+    } \+    \+    template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+    void operator()( \+        ASIO_MOVE_ARG(Handler) handler, \+        ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    { \+      initiation_( \+          cancellation_slot_binder< \+            typename decay<Handler>::type, CancellationSlot>( \+              slot_, ASIO_MOVE_CAST(Handler)(handler)), \+          ASIO_VARIADIC_MOVE_ARGS(n)); \+    } \+    /**/+    ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    CancellationSlot slot_;+    Initiation initiation_;   }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,-        Signature>(-        declval<init_wrapper<decay_t<Initiation>>>(),-        token.get(), token.get_cancellation_slot(),-        static_cast<Args&&>(args)...))+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+    (async_initiate<T, Signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<RawCompletionToken>().get(),+        declval<ASIO_MOVE_ARG(Args)>()...)))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)   {-    return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,-      Signature>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.get(), token.get_cancellation_slot(),-        static_cast<Args&&>(args)...);+    return async_initiate<T, Signature>(+        init_wrapper<typename decay<Initiation>::type>(+          token.get_cancellation_slot(),+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.get(), ASIO_MOVE_CAST(Args)(args)...);   } -private:-  async_result(const async_result&) = delete;-  async_result& operator=(const async_result&) = delete;--  async_result<T, Signature> target_;-};+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename CancellationSlot, typename... Signatures>-struct async_result<partial_cancellation_slot_binder<CancellationSlot>,-    Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        cancellation_slot_binder<-          default_completion_token_t<associated_executor_t<Initiation>>,-          CancellationSlot>(token.cancellation_slot_,-            default_completion_token_t<associated_executor_t<Initiation>>{}),-        static_cast<Args&&>(args)...))+  template <typename Initiation, typename RawCompletionToken>+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+    (async_initiate<T, Signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<RawCompletionToken>().get())))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token)   {-    return async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        cancellation_slot_binder<-          default_completion_token_t<associated_executor_t<Initiation>>,-          CancellationSlot>(token.cancellation_slot_,-            default_completion_token_t<associated_executor_t<Initiation>>{}),-        static_cast<Args&&>(args)...);+    return async_initiate<T, Signature>(+        init_wrapper<typename decay<Initiation>::type>(+          token.get_cancellation_slot(),+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.get());   }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, typename RawCompletionToken, \+      ASIO_VARIADIC_TPARAMS(n)> \+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \+    (async_initiate<T, Signature>( \+        declval<init_wrapper<typename decay<Initiation>::type> >(), \+        declval<RawCompletionToken>().get(), \+        ASIO_VARIADIC_MOVE_DECLVAL(n)))) \+  initiate( \+      ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_MOVE_ARG(RawCompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return async_initiate<T, Signature>( \+        init_wrapper<typename decay<Initiation>::type>( \+          token.get_cancellation_slot(), \+          ASIO_MOVE_CAST(Initiation)(initiation)), \+        token.get(), ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+  async_result(const async_result&) ASIO_DELETED;+  async_result& operator=(const async_result&) ASIO_DELETED;++  async_result<T, Signature> target_; };  template <template <typename, typename> class Associator,@@ -582,15 +693,19 @@     DefaultCandidate>   : Associator<T, DefaultCandidate> {-  static typename Associator<T, DefaultCandidate>::type get(-      const cancellation_slot_binder<T, CancellationSlot>& b) noexcept+  static typename Associator<T, DefaultCandidate>::type+  get(const cancellation_slot_binder<T, CancellationSlot>& b)+    ASIO_NOEXCEPT   {     return Associator<T, DefaultCandidate>::get(b.get());   } -  static auto get(const cancellation_slot_binder<T, CancellationSlot>& b,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<T, DefaultCandidate>::type)+  get(const cancellation_slot_binder<T, CancellationSlot>& b,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<T, DefaultCandidate>::get(b.get(), c)))   {     return Associator<T, DefaultCandidate>::get(b.get(), c);   }@@ -603,9 +718,10 @@ {   typedef CancellationSlot type; -  static auto get(const cancellation_slot_binder<T, CancellationSlot>& b,-      const CancellationSlot1& = CancellationSlot1()) noexcept-    -> decltype(b.get_cancellation_slot())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const cancellation_slot_binder<T, CancellationSlot>& b,+      const CancellationSlot1& = CancellationSlot1()) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((b.get_cancellation_slot()))   {     return b.get_cancellation_slot();   }
link/modules/asio-standalone/asio/include/asio/bind_executor.hpp view
@@ -2,7 +2,7 @@ // bind_executor.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,11 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/associated_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp" #include "asio/execution_context.hpp" #include "asio/is_executor.hpp"@@ -41,7 +41,8 @@ };  template <typename T>-struct executor_binder_result_type<T, void_t<typename T::result_type>>+struct executor_binder_result_type<T,+  typename void_type<typename T::result_type>::type> {   typedef typename T::result_type result_type; protected:@@ -102,7 +103,8 @@ struct executor_binder_argument_type {};  template <typename T>-struct executor_binder_argument_type<T, void_t<typename T::argument_type>>+struct executor_binder_argument_type<T,+  typename void_type<typename T::argument_type>::type> {   typedef typename T::argument_type argument_type; };@@ -127,7 +129,7 @@  template <typename T> struct executor_binder_argument_types<T,-    void_t<typename T::first_argument_type>>+  typename void_type<typename T::first_argument_type>::type> {   typedef typename T::first_argument_type first_argument_type;   typedef typename T::second_argument_type second_argument_type;@@ -158,9 +160,9 @@ { protected:   template <typename E, typename U>-  executor_binder_base(E&& e, U&& u)-    : executor_(static_cast<E&&>(e)),-      target_(executor_arg_t(), executor_, static_cast<U&&>(u))+  executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u)+    : executor_(ASIO_MOVE_CAST(E)(e)),+      target_(executor_arg_t(), executor_, ASIO_MOVE_CAST(U)(u))   {   } @@ -173,9 +175,9 @@ { protected:   template <typename E, typename U>-  executor_binder_base(E&& e, U&& u)-    : executor_(static_cast<E&&>(e)),-      target_(static_cast<U&&>(u))+  executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u)+    : executor_(ASIO_MOVE_CAST(E)(e)),+      target_(ASIO_MOVE_CAST(U)(u))   {   } @@ -183,6 +185,21 @@   T target_; }; +// Helper to enable SFINAE on zero-argument operator() below.++template <typename T, typename = void>+struct executor_binder_result_of0+{+  typedef void type;+};++template <typename T>+struct executor_binder_result_of0<T,+  typename void_type<typename result_of<T()>::type>::type>+{+  typedef typename result_of<T()>::type type;+};+ } // namespace detail  /// A call wrapper type to bind an executor of type @c Executor to an object of@@ -273,8 +290,8 @@    */   template <typename U>   executor_binder(executor_arg_t, const executor_type& e,-      U&& u)-    : base_type(e, static_cast<U&&>(u))+      ASIO_MOVE_ARG(U) u)+    : base_type(e, ASIO_MOVE_CAST(U)(u))   {   } @@ -298,9 +315,7 @@    * @c U.    */   template <typename U, typename OtherExecutor>-  executor_binder(const executor_binder<U, OtherExecutor>& other,-      constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,-      constraint_t<is_constructible<T, U>::value> = 0)+  executor_binder(const executor_binder<U, OtherExecutor>& other)     : base_type(other.get_executor(), other.get())   {   }@@ -313,33 +328,32 @@    */   template <typename U, typename OtherExecutor>   executor_binder(executor_arg_t, const executor_type& e,-      const executor_binder<U, OtherExecutor>& other,-      constraint_t<is_constructible<T, U>::value> = 0)+      const executor_binder<U, OtherExecutor>& other)     : base_type(e, other.get())   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+   /// Move constructor.   executor_binder(executor_binder&& other)-    : base_type(static_cast<executor_type&&>(other.get_executor()),-        static_cast<T&&>(other.get()))+    : base_type(ASIO_MOVE_CAST(executor_type)(other.get_executor()),+        ASIO_MOVE_CAST(T)(other.get()))   {   }    /// Move construct the target object, but specify a different executor.   executor_binder(executor_arg_t, const executor_type& e,       executor_binder&& other)-    : base_type(e, static_cast<T&&>(other.get()))+    : base_type(e, ASIO_MOVE_CAST(T)(other.get()))   {   }    /// Move construct from a different executor wrapper type.   template <typename U, typename OtherExecutor>-  executor_binder(executor_binder<U, OtherExecutor>&& other,-      constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,-      constraint_t<is_constructible<T, U>::value> = 0)-    : base_type(static_cast<OtherExecutor&&>(other.get_executor()),-        static_cast<U&&>(other.get()))+  executor_binder(executor_binder<U, OtherExecutor>&& other)+    : base_type(ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()),+        ASIO_MOVE_CAST(U)(other.get()))   {   } @@ -347,141 +361,152 @@   /// different executor.   template <typename U, typename OtherExecutor>   executor_binder(executor_arg_t, const executor_type& e,-      executor_binder<U, OtherExecutor>&& other,-      constraint_t<is_constructible<T, U>::value> = 0)-    : base_type(e, static_cast<U&&>(other.get()))+      executor_binder<U, OtherExecutor>&& other)+    : base_type(e, ASIO_MOVE_CAST(U)(other.get()))   {   } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+   /// Destructor.   ~executor_binder()   {   }    /// Obtain a reference to the target object.-  target_type& get() noexcept+  target_type& get() ASIO_NOEXCEPT   {     return this->target_;   }    /// Obtain a reference to the target object.-  const target_type& get() const noexcept+  const target_type& get() const ASIO_NOEXCEPT   {     return this->target_;   }    /// Obtain the associated executor.-  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return this->executor_;   } +#if defined(GENERATING_DOCUMENTATION)++  template <typename... Args> auto operator()(Args&& ...);+  template <typename... Args> auto operator()(Args&& ...) const;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)+   /// Forwarding function call operator.   template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) &+  typename result_of<T(Args...)>::type operator()(+      ASIO_MOVE_ARG(Args)... args)   {-    return this->target_(static_cast<Args&&>(args)...);+    return this->target_(ASIO_MOVE_CAST(Args)(args)...);   }    /// Forwarding function call operator.   template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) &&+  typename result_of<T(Args...)>::type operator()(+      ASIO_MOVE_ARG(Args)... args) const   {-    return static_cast<T&&>(this->target_)(static_cast<Args&&>(args)...);+    return this->target_(ASIO_MOVE_CAST(Args)(args)...);   } -  /// Forwarding function call operator.-  template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) const&+#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++  typename detail::executor_binder_result_of0<T>::type operator()()   {-    return this->target_(static_cast<Args&&>(args)...);+    return this->target_();   } -private:-  typedef detail::executor_binder_base<T, Executor,-    uses_executor<T, Executor>::value> base_type;-};+  typename detail::executor_binder_result_of0<T>::type operator()() const+  {+    return this->target_();+  } -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler should have the supplied executor as its associated-/// executor.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Executor>-struct partial_executor_binder-{-  /// Constructor that specifies associated executor.-  explicit partial_executor_binder(const Executor& ex)-    : executor_(ex)+#define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) const \+  { \+    return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)+#undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF++#else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++  typedef typename detail::executor_binder_result_type<T>::result_type_or_void+    result_type_or_void;++  result_type_or_void operator()()   {+    return this->target_();   } -  /// Adapt a @ref completion_token to specify that the completion handler-  /// should have the executor as its associated executor.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  constexpr executor_binder<decay_t<CompletionToken>, Executor>-  operator()(CompletionToken&& completion_token) const+  result_type_or_void operator()() const   {-    return executor_binder<decay_t<CompletionToken>, Executor>(executor_arg_t(),-        static_cast<CompletionToken&&>(completion_token), executor_);+    return this->target_();   } -//private:-  Executor executor_;-};+#define ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  result_type_or_void operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  result_type_or_void operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) const \+  { \+    return this->target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)+#undef ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF -/// Create a partial completion token that associates an executor.-template <typename Executor>-ASIO_NODISCARD inline partial_executor_binder<Executor>-bind_executor(const Executor& ex,-    constraint_t<-      is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)-{-  return partial_executor_binder<Executor>(ex);-}+#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER) +private:+  typedef detail::executor_binder_base<T, Executor,+    uses_executor<T, Executor>::value> base_type;+};+ /// Associate an object of type @c T with an executor of type @c Executor. template <typename Executor, typename T>-ASIO_NODISCARD inline executor_binder<decay_t<T>, Executor>-bind_executor(const Executor& ex, T&& t,-    constraint_t<+ASIO_NODISCARD inline executor_binder<typename decay<T>::type, Executor>+bind_executor(const Executor& ex, ASIO_MOVE_ARG(T) t,+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)-{-  return executor_binder<decay_t<T>, Executor>(-      executor_arg_t(), ex, static_cast<T&&>(t));-}--/// Create a partial completion token that associates an execution context's-/// executor.-template <typename ExecutionContext>-ASIO_NODISCARD inline partial_executor_binder<-    typename ExecutionContext::executor_type>-bind_executor(ExecutionContext& ctx,-    constraint_t<-      is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)+    >::type = 0) {-  return partial_executor_binder<typename ExecutionContext::executor_type>(-      ctx.get_executor());+  return executor_binder<typename decay<T>::type, Executor>(+      executor_arg_t(), ex, ASIO_MOVE_CAST(T)(t)); }  /// Associate an object of type @c T with an execution context's executor. template <typename ExecutionContext, typename T>-ASIO_NODISCARD inline executor_binder<decay_t<T>,-    typename ExecutionContext::executor_type>-bind_executor(ExecutionContext& ctx, T&& t,-    constraint_t<-      is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)+ASIO_NODISCARD inline executor_binder<typename decay<T>::type,+  typename ExecutionContext::executor_type>+bind_executor(ExecutionContext& ctx, ASIO_MOVE_ARG(T) t,+    typename constraint<is_convertible<+      ExecutionContext&, execution_context&>::value>::type = 0) {-  return executor_binder<decay_t<T>, typename ExecutionContext::executor_type>(-      executor_arg_t(), ctx.get_executor(), static_cast<T&&>(t));+  return executor_binder<typename decay<T>::type,+    typename ExecutionContext::executor_type>(+      executor_arg_t(), ctx.get_executor(), ASIO_MOVE_CAST(T)(t)); }  #if !defined(GENERATING_DOCUMENTATION)@@ -504,12 +529,11 @@  template <typename TargetAsyncResult, typename Executor> class executor_binder_completion_handler_async_result<-    TargetAsyncResult, Executor,-    void_t<typename TargetAsyncResult::completion_handler_type >>+  TargetAsyncResult, Executor,+  typename void_type<+    typename TargetAsyncResult::completion_handler_type+  >::type> {-private:-  TargetAsyncResult target_;- public:   typedef executor_binder<     typename TargetAsyncResult::completion_handler_type, Executor>@@ -521,10 +545,13 @@   {   } -  auto get() -> decltype(target_.get())+  typename TargetAsyncResult::return_type get()   {     return target_.get();   }++private:+  TargetAsyncResult target_; };  template <typename TargetAsyncResult, typename = void>@@ -533,8 +560,11 @@ };  template <typename TargetAsyncResult>-struct executor_binder_async_result_return_type<TargetAsyncResult,-    void_t<typename TargetAsyncResult::return_type>>+struct executor_binder_async_result_return_type<+  TargetAsyncResult,+  typename void_type<+    typename TargetAsyncResult::return_type+  >::type> {   typedef typename TargetAsyncResult::return_type return_type; };@@ -544,9 +574,9 @@ template <typename T, typename Executor, typename Signature> class async_result<executor_binder<T, Executor>, Signature> :   public detail::executor_binder_completion_handler_async_result<-      async_result<T, Signature>, Executor>,+    async_result<T, Signature>, Executor>,   public detail::executor_binder_async_result_return_type<-      async_result<T, Signature>>+    async_result<T, Signature> > { public:   explicit async_result(executor_binder<T, Executor>& b)@@ -556,78 +586,154 @@   }    template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;+    template <typename Init>+    init_wrapper(const Executor& ex, ASIO_MOVE_ARG(Init) init)+      : ex_(ex),+        initiation_(ASIO_MOVE_CAST(Init)(init))+    {+    } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+     template <typename Handler, typename... Args>-    void operator()(Handler&& handler, const Executor& e, Args&&... args) &&+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<Initiation&&>(*this)(-          executor_binder<decay_t<Handler>, Executor>(-            executor_arg_t(), e, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          executor_binder<typename decay<Handler>::type, Executor>(+            executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        const Executor& e, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args) const     {-      static_cast<const Initiation&>(*this)(-          executor_binder<decay_t<Handler>, Executor>(-            executor_arg_t(), e, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      initiation_(+          executor_binder<typename decay<Handler>::type, Executor>(+            executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    template <typename Handler>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler)+    {+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          executor_binder<typename decay<Handler>::type, Executor>(+            executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)));+    }++    template <typename Handler>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler) const+    {+      initiation_(+          executor_binder<typename decay<Handler>::type, Executor>(+            executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)));+    }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+    template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+    void operator()( \+        ASIO_MOVE_ARG(Handler) handler, \+        ASIO_VARIADIC_MOVE_PARAMS(n)) \+    { \+      ASIO_MOVE_CAST(Initiation)(initiation_)( \+          executor_binder<typename decay<Handler>::type, Executor>( \+            executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)), \+          ASIO_VARIADIC_MOVE_ARGS(n)); \+    } \+    \+    template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+    void operator()( \+        ASIO_MOVE_ARG(Handler) handler, \+        ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    { \+      initiation_( \+          executor_binder<typename decay<Handler>::type, Executor>( \+            executor_arg_t(), ex_, ASIO_MOVE_CAST(Handler)(handler)), \+          ASIO_VARIADIC_MOVE_ARGS(n)); \+    } \+    /**/+    ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    Executor ex_;+    Initiation initiation_;   }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,-        Signature>(-          declval<init_wrapper<decay_t<Initiation>>>(),-          token.get(), token.get_executor(), static_cast<Args&&>(args)...))+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+    (async_initiate<T, Signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<RawCompletionToken>().get(),+        declval<ASIO_MOVE_ARG(Args)>()...)))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)   {-    return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,-      Signature>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.get(), token.get_executor(), static_cast<Args&&>(args)...);+    return async_initiate<T, Signature>(+        init_wrapper<typename decay<Initiation>::type>(+          token.get_executor(), ASIO_MOVE_CAST(Initiation)(initiation)),+        token.get(), ASIO_MOVE_CAST(Args)(args)...);   } -private:-  async_result(const async_result&) = delete;-  async_result& operator=(const async_result&) = delete;-};+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename Executor, typename... Signatures>-struct async_result<partial_executor_binder<Executor>, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        executor_binder<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Executor>(executor_arg_t(), token.executor_,-            default_completion_token_t<associated_executor_t<Initiation>>{}),-        static_cast<Args&&>(args)...))+  template <typename Initiation, typename RawCompletionToken>+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+    (async_initiate<T, Signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<RawCompletionToken>().get())))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token)   {-    return async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        executor_binder<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Executor>(executor_arg_t(), token.executor_,-            default_completion_token_t<associated_executor_t<Initiation>>{}),-        static_cast<Args&&>(args)...);+    return async_initiate<T, Signature>(+        init_wrapper<typename decay<Initiation>::type>(+          token.get_executor(), ASIO_MOVE_CAST(Initiation)(initiation)),+        token.get());   }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, typename RawCompletionToken, \+      ASIO_VARIADIC_TPARAMS(n)> \+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \+    (async_initiate<T, Signature>( \+        declval<init_wrapper<typename decay<Initiation>::type> >(), \+        declval<RawCompletionToken>().get(), \+        ASIO_VARIADIC_MOVE_DECLVAL(n)))) \+  initiate( \+      ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_MOVE_ARG(RawCompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return async_initiate<T, Signature>( \+        init_wrapper<typename decay<Initiation>::type>( \+          token.get_executor(), ASIO_MOVE_CAST(Initiation)(initiation)), \+        token.get(), ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+  async_result(const async_result&) ASIO_DELETED;+  async_result& operator=(const async_result&) ASIO_DELETED; };  template <template <typename, typename> class Associator,@@ -635,15 +741,18 @@ struct associator<Associator, executor_binder<T, Executor>, DefaultCandidate>   : Associator<T, DefaultCandidate> {-  static typename Associator<T, DefaultCandidate>::type get(-      const executor_binder<T, Executor>& b) noexcept+  static typename Associator<T, DefaultCandidate>::type+  get(const executor_binder<T, Executor>& b) ASIO_NOEXCEPT   {     return Associator<T, DefaultCandidate>::get(b.get());   } -  static auto get(const executor_binder<T, Executor>& b,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<T, DefaultCandidate>::type)+  get(const executor_binder<T, Executor>& b,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<T, DefaultCandidate>::get(b.get(), c)))   {     return Associator<T, DefaultCandidate>::get(b.get(), c);   }@@ -654,9 +763,10 @@ {   typedef Executor type; -  static auto get(const executor_binder<T, Executor>& b,-      const Executor1& = Executor1()) noexcept-    -> decltype(b.get_executor())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const executor_binder<T, Executor>& b,+      const Executor1& = Executor1()) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((b.get_executor()))   {     return b.get_executor();   }
link/modules/asio-standalone/asio/include/asio/bind_immediate_executor.hpp view
@@ -1,8 +1,8 @@ // // bind_immediate_executor.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+// ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,12 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/associated_immediate_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/type_traits.hpp"  #include "asio/detail/push_options.hpp" @@ -38,7 +37,8 @@ };  template <typename T>-struct immediate_executor_binder_result_type<T, void_t<typename T::result_type>>+struct immediate_executor_binder_result_type<T,+  typename void_type<typename T::result_type>::type> {   typedef typename T::result_type result_type; protected:@@ -100,7 +100,7 @@  template <typename T> struct immediate_executor_binder_argument_type<T,-  void_t<typename T::argument_type>>+  typename void_type<typename T::argument_type>::type> {   typedef typename T::argument_type argument_type; };@@ -125,7 +125,7 @@  template <typename T> struct immediate_executor_binder_argument_types<T,-  void_t<typename T::first_argument_type>>+  typename void_type<typename T::first_argument_type>::type> {   typedef typename T::first_argument_type first_argument_type;   typedef typename T::second_argument_type second_argument_type;@@ -145,6 +145,21 @@   typedef A2 second_argument_type; }; +// Helper to enable SFINAE on zero-argument operator() below.++template <typename T, typename = void>+struct immediate_executor_binder_result_of0+{+  typedef void type;+};++template <typename T>+struct immediate_executor_binder_result_of0<T,+  typename void_type<typename result_of<T()>::type>::type>+{+  typedef typename result_of<T()>::type type;+};+ } // namespace detail  /// A call wrapper type to bind a immediate executor of type @c Executor@@ -233,9 +248,9 @@    */   template <typename U>   immediate_executor_binder(const immediate_executor_type& e,-      U&& u)+      ASIO_MOVE_ARG(U) u)     : executor_(e),-      target_(static_cast<U&&>(u))+      target_(ASIO_MOVE_CAST(U)(u))   {   } @@ -262,9 +277,7 @@    */   template <typename U, typename OtherExecutor>   immediate_executor_binder(-      const immediate_executor_binder<U, OtherExecutor>& other,-      constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,-      constraint_t<is_constructible<T, U>::value> = 0)+      const immediate_executor_binder<U, OtherExecutor>& other)     : executor_(other.get_immediate_executor()),       target_(other.get())   {@@ -278,18 +291,19 @@    */   template <typename U, typename OtherExecutor>   immediate_executor_binder(const immediate_executor_type& e,-      const immediate_executor_binder<U, OtherExecutor>& other,-      constraint_t<is_constructible<T, U>::value> = 0)+      const immediate_executor_binder<U, OtherExecutor>& other)     : executor_(e),       target_(other.get())   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+   /// Move constructor.   immediate_executor_binder(immediate_executor_binder&& other)-    : executor_(static_cast<immediate_executor_type&&>(+    : executor_(ASIO_MOVE_CAST(immediate_executor_type)(           other.get_immediate_executor())),-      target_(static_cast<T&&>(other.get()))+      target_(ASIO_MOVE_CAST(T)(other.get()))   {   } @@ -298,19 +312,17 @@   immediate_executor_binder(const immediate_executor_type& e,       immediate_executor_binder&& other)     : executor_(e),-      target_(static_cast<T&&>(other.get()))+      target_(ASIO_MOVE_CAST(T)(other.get()))   {   }    /// Move construct from a different immediate executor wrapper type.   template <typename U, typename OtherExecutor>   immediate_executor_binder(-      immediate_executor_binder<U, OtherExecutor>&& other,-      constraint_t<is_constructible<Executor, OtherExecutor>::value> = 0,-      constraint_t<is_constructible<T, U>::value> = 0)-    : executor_(static_cast<OtherExecutor&&>(+      immediate_executor_binder<U, OtherExecutor>&& other)+    : executor_(ASIO_MOVE_CAST(OtherExecutor)(           other.get_immediate_executor())),-      target_(static_cast<U&&>(other.get()))+      target_(ASIO_MOVE_CAST(U)(other.get()))   {   } @@ -318,152 +330,163 @@   /// specify a different immediate executor.   template <typename U, typename OtherExecutor>   immediate_executor_binder(const immediate_executor_type& e,-      immediate_executor_binder<U, OtherExecutor>&& other,-      constraint_t<is_constructible<T, U>::value> = 0)+      immediate_executor_binder<U, OtherExecutor>&& other)     : executor_(e),-      target_(static_cast<U&&>(other.get()))+      target_(ASIO_MOVE_CAST(U)(other.get()))   {   } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+   /// Destructor.   ~immediate_executor_binder()   {   }    /// Obtain a reference to the target object.-  target_type& get() noexcept+  target_type& get() ASIO_NOEXCEPT   {     return target_;   }    /// Obtain a reference to the target object.-  const target_type& get() const noexcept+  const target_type& get() const ASIO_NOEXCEPT   {     return target_;   }    /// Obtain the associated immediate executor.-  immediate_executor_type get_immediate_executor() const noexcept+  immediate_executor_type get_immediate_executor() const ASIO_NOEXCEPT   {     return executor_;   } +#if defined(GENERATING_DOCUMENTATION)++  template <typename... Args> auto operator()(Args&& ...);+  template <typename... Args> auto operator()(Args&& ...) const;++#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)+   /// Forwarding function call operator.   template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) &+  typename result_of<T(Args...)>::type operator()(+      ASIO_MOVE_ARG(Args)... args)   {-    return target_(static_cast<Args&&>(args)...);+    return target_(ASIO_MOVE_CAST(Args)(args)...);   }    /// Forwarding function call operator.   template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) &&+  typename result_of<T(Args...)>::type operator()(+      ASIO_MOVE_ARG(Args)... args) const   {-    return static_cast<T&&>(target_)(static_cast<Args&&>(args)...);+    return target_(ASIO_MOVE_CAST(Args)(args)...);   } -  /// Forwarding function call operator.-  template <typename... Args>-  result_of_t<T(Args...)> operator()(Args&&... args) const&+#elif defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++  typename detail::immediate_executor_binder_result_of0<T>::type operator()()   {-    return target_(static_cast<Args&&>(args)...);+    return target_();   } -private:-  Executor executor_;-  T target_;-};+  typename detail::immediate_executor_binder_result_of0<T>::type+  operator()() const+  {+    return target_();+  } -/// A function object type that adapts a @ref completion_token to specify that-/// the completion handler should have the supplied executor as its associated-/// immediate executor.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Executor>-struct partial_immediate_executor_binder-{-  /// Constructor that specifies associated executor.-  explicit partial_immediate_executor_binder(const Executor& ex)-    : executor_(ex)+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  typename result_of<T(ASIO_VARIADIC_TARGS(n))>::type operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) const \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#else // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++  typedef typename detail::immediate_executor_binder_result_type<+    T>::result_type_or_void result_type_or_void;++  result_type_or_void operator()()   {+    return target_();   } -  /// Adapt a @ref completion_token to specify that the completion handler-  /// should have the executor as its associated immediate executor.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  constexpr immediate_executor_binder<decay_t<CompletionToken>, Executor>-  operator()(CompletionToken&& completion_token) const+  result_type_or_void operator()() const   {-    return immediate_executor_binder<decay_t<CompletionToken>, Executor>(-        static_cast<CompletionToken&&>(completion_token), executor_);+    return target_();   } -//private:+#define ASIO_PRIVATE_BINDER_CALL_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  result_type_or_void operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  result_type_or_void operator()( \+      ASIO_VARIADIC_MOVE_PARAMS(n)) const \+  { \+    return target_(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_BINDER_CALL_DEF)+#undef ASIO_PRIVATE_BINDER_CALL_DEF++#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)++private:   Executor executor_;+  T target_; }; -/// Create a partial completion token that associates an executor.-template <typename Executor>-ASIO_NODISCARD inline partial_immediate_executor_binder<Executor>-bind_immediate_executor(const Executor& ex)-{-  return partial_immediate_executor_binder<Executor>(ex);-}- /// Associate an object of type @c T with a immediate executor of type /// @c Executor. template <typename Executor, typename T>-ASIO_NODISCARD inline immediate_executor_binder<decay_t<T>, Executor>-bind_immediate_executor(const Executor& e, T&& t)+ASIO_NODISCARD inline+immediate_executor_binder<typename decay<T>::type, Executor>+bind_immediate_executor(const Executor& e, ASIO_MOVE_ARG(T) t) {   return immediate_executor_binder<-    decay_t<T>, Executor>(-      e, static_cast<T&&>(t));+    typename decay<T>::type, Executor>(+      e, ASIO_MOVE_CAST(T)(t)); }  #if !defined(GENERATING_DOCUMENTATION)  namespace detail { -template <typename TargetAsyncResult, typename Executor, typename = void>-class immediate_executor_binder_completion_handler_async_result+template <typename TargetAsyncResult,+  typename Executor, typename = void>+struct immediate_executor_binder_async_result_completion_handler_type {-public:-  template <typename T>-  explicit immediate_executor_binder_completion_handler_async_result(T&)-  {-  } };  template <typename TargetAsyncResult, typename Executor>-class immediate_executor_binder_completion_handler_async_result<+struct immediate_executor_binder_async_result_completion_handler_type<   TargetAsyncResult, Executor,-  void_t<+  typename void_type<     typename TargetAsyncResult::completion_handler_type-  >>+  >::type> {-private:-  TargetAsyncResult target_;--public:   typedef immediate_executor_binder<     typename TargetAsyncResult::completion_handler_type, Executor>       completion_handler_type;--  explicit immediate_executor_binder_completion_handler_async_result(-      typename TargetAsyncResult::completion_handler_type& handler)-    : target_(handler)-  {-  }--  auto get() -> decltype(target_.get())-  {-    return target_.get();-  } };  template <typename TargetAsyncResult, typename = void>@@ -474,9 +497,9 @@ template <typename TargetAsyncResult> struct immediate_executor_binder_async_result_return_type<   TargetAsyncResult,-  void_t<+  typename void_type<     typename TargetAsyncResult::return_type-  >>+  >::type> {   typedef typename TargetAsyncResult::return_type return_type; };@@ -485,97 +508,182 @@  template <typename T, typename Executor, typename Signature> class async_result<immediate_executor_binder<T, Executor>, Signature> :-  public detail::immediate_executor_binder_completion_handler_async_result<+  public detail::immediate_executor_binder_async_result_completion_handler_type<     async_result<T, Signature>, Executor>,   public detail::immediate_executor_binder_async_result_return_type<-    async_result<T, Signature>>+    async_result<T, Signature> > { public:   explicit async_result(immediate_executor_binder<T, Executor>& b)-    : detail::immediate_executor_binder_completion_handler_async_result<-        async_result<T, Signature>, Executor>(b.get())+    : target_(b.get())   {   } +  typename async_result<T, Signature>::return_type get()+  {+    return target_.get();+  }+   template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;+    template <typename Init>+    init_wrapper(const Executor& e, ASIO_MOVE_ARG(Init) init)+      : executor_(e),+        initiation_(ASIO_MOVE_CAST(Init)(init))+    {+    } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+     template <typename Handler, typename... Args>-    void operator()(Handler&& handler, const Executor& e, Args&&... args) &&+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<Initiation&&>(*this)(+      ASIO_MOVE_CAST(Initiation)(initiation_)(           immediate_executor_binder<-            decay_t<Handler>, Executor>(-              e, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+            typename decay<Handler>::type, Executor>(+              executor_, ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        const Executor& e, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args) const     {-      static_cast<const Initiation&>(*this)(+      initiation_(           immediate_executor_binder<-            decay_t<Handler>, Executor>(-              e, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+            typename decay<Handler>::type, Executor>(+              executor_, ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    template <typename Handler>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler)+    {+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          immediate_executor_binder<+            typename decay<Handler>::type, Executor>(+              executor_, ASIO_MOVE_CAST(Handler)(handler)));+    }++    template <typename Handler>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler) const+    {+      initiation_(+          immediate_executor_binder<+            typename decay<Handler>::type, Executor>(+              executor_, ASIO_MOVE_CAST(Handler)(handler)));+    }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+    template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+    void operator()( \+        ASIO_MOVE_ARG(Handler) handler, \+        ASIO_VARIADIC_MOVE_PARAMS(n)) \+    { \+      ASIO_MOVE_CAST(Initiation)(initiation_)( \+          immediate_executor_binder< \+            typename decay<Handler>::type, Executor>( \+              executor_, ASIO_MOVE_CAST(Handler)(handler)), \+          ASIO_VARIADIC_MOVE_ARGS(n)); \+    } \+    \+    template <typename Handler, ASIO_VARIADIC_TPARAMS(n)> \+    void operator()( \+        ASIO_MOVE_ARG(Handler) handler, \+        ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    { \+      initiation_( \+          immediate_executor_binder< \+            typename decay<Handler>::type, Executor>( \+              executor_, ASIO_MOVE_CAST(Handler)(handler)), \+          ASIO_VARIADIC_MOVE_ARGS(n)); \+    } \+    /**/+    ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    Executor executor_;+    Initiation initiation_;   }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,-        Signature>(-          declval<init_wrapper<decay_t<Initiation>>>(),-          token.get(), token.get_immediate_executor(),-          static_cast<Args&&>(args)...))+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+    (async_initiate<T, Signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<RawCompletionToken>().get(),+        declval<ASIO_MOVE_ARG(Args)>()...)))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)   {-    return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value, const T, T>,-      Signature>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.get(), token.get_immediate_executor(),-        static_cast<Args&&>(args)...);+    return async_initiate<T, Signature>(+        init_wrapper<typename decay<Initiation>::type>(+          token.get_immediate_executor(),+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.get(), ASIO_MOVE_CAST(Args)(args)...);   } -private:-  async_result(const async_result&) = delete;-  async_result& operator=(const async_result&) = delete;--  async_result<T, Signature> target_;-};+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename Executor, typename... Signatures>-struct async_result<partial_immediate_executor_binder<Executor>, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        immediate_executor_binder<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Executor>(token.executor_,-            default_completion_token_t<associated_executor_t<Initiation>>{}),-        static_cast<Args&&>(args)...))+  template <typename Initiation, typename RawCompletionToken>+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature,+    (async_initiate<T, Signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<RawCompletionToken>().get())))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token)   {-    return async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        immediate_executor_binder<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Executor>(token.executor_,-            default_completion_token_t<associated_executor_t<Initiation>>{}),-        static_cast<Args&&>(args)...);+    return async_initiate<T, Signature>(+        init_wrapper<typename decay<Initiation>::type>(+          token.get_immediate_executor(),+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.get());   }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, typename RawCompletionToken, \+      ASIO_VARIADIC_TPARAMS(n)> \+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(T, Signature, \+    (async_initiate<T, Signature>( \+        declval<init_wrapper<typename decay<Initiation>::type> >(), \+        declval<RawCompletionToken>().get(), \+        ASIO_VARIADIC_MOVE_DECLVAL(n)))) \+  initiate( \+      ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_MOVE_ARG(RawCompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return async_initiate<T, Signature>( \+        init_wrapper<typename decay<Initiation>::type>( \+          token.get_immediate_executor(), \+          ASIO_MOVE_CAST(Initiation)(initiation)), \+        token.get(), ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++private:+  async_result(const async_result&) ASIO_DELETED;+  async_result& operator=(const async_result&) ASIO_DELETED;++  async_result<T, Signature> target_; };  template <template <typename, typename> class Associator,@@ -585,15 +693,19 @@     DefaultCandidate>   : Associator<T, DefaultCandidate> {-  static typename Associator<T, DefaultCandidate>::type get(-      const immediate_executor_binder<T, Executor>& b) noexcept+  static typename Associator<T, DefaultCandidate>::type+  get(const immediate_executor_binder<T, Executor>& b)+    ASIO_NOEXCEPT   {     return Associator<T, DefaultCandidate>::get(b.get());   } -  static auto get(const immediate_executor_binder<T, Executor>& b,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<T, DefaultCandidate>::get(b.get(), c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<T, DefaultCandidate>::type)+  get(const immediate_executor_binder<T, Executor>& b,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<T, DefaultCandidate>::get(b.get(), c)))   {     return Associator<T, DefaultCandidate>::get(b.get(), c);   }@@ -606,9 +718,10 @@ {   typedef Executor type; -  static auto get(const immediate_executor_binder<T, Executor>& b,-      const Executor1& = Executor1()) noexcept-    -> decltype(b.get_immediate_executor())+  static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(+      const immediate_executor_binder<T, Executor>& b,+      const Executor1& = Executor1()) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((b.get_immediate_executor()))   {     return b.get_immediate_executor();   }
link/modules/asio-standalone/asio/include/asio/buffer.hpp view
@@ -2,2878 +2,2906 @@ // buffer.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_BUFFER_HPP-#define ASIO_BUFFER_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include <cstddef>-#include <cstring>-#include <limits>-#include <stdexcept>-#include <string>-#include <vector>-#include "asio/detail/array_fwd.hpp"-#include "asio/detail/memory.hpp"-#include "asio/detail/string_view.hpp"-#include "asio/detail/throw_exception.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/is_contiguous_iterator.hpp"--#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1700)-# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)-#  if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)-#   define ASIO_ENABLE_BUFFER_DEBUGGING-#  endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)-# endif // defined(_HAS_ITERATOR_DEBUGGING)-#endif // defined(ASIO_MSVC) && (ASIO_MSVC >= 1700)--#if defined(__GNUC__)-# if defined(_GLIBCXX_DEBUG)-#  if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)-#   define ASIO_ENABLE_BUFFER_DEBUGGING-#  endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)-# endif // defined(_GLIBCXX_DEBUG)-#endif // defined(__GNUC__)--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-# include "asio/detail/functional.hpp"-#endif // ASIO_ENABLE_BUFFER_DEBUGGING--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--#if defined(ASIO_MSVC)--struct span_memfns_base-{-  void subspan();-};--template <typename T>-struct span_memfns_derived : T, span_memfns_base-{-};--template <typename T, T>-struct span_memfns_check-{-};--template <typename>-char (&subspan_memfn_helper(...))[2];--template <typename T>-char subspan_memfn_helper(-    span_memfns_check<-      void (span_memfns_base::*)(),-      &span_memfns_derived<T>::subspan>*);--template <typename T>-struct has_subspan_memfn :-  integral_constant<bool, sizeof(subspan_memfn_helper<T>(0)) != 1>-{-};--#endif // defined(ASIO_MSVC)--} // namespace detail--class mutable_buffer;-class const_buffer;--/// Holds a buffer that can be modified.-/**- * The mutable_buffer class provides a safe representation of a buffer that can- * be modified. It does not own the underlying data, and so is cheap to copy or- * assign.- *- * @par Accessing Buffer Contents- *- * 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 = b1.size();- * unsigned char* p1 = static_cast<unsigned char*>(b1.data());- * @endcode- *- * The @c data() member function permits violations of type safety, so uses of- * it in application code should be carefully considered.- */-class mutable_buffer-{-public:-  /// Construct an empty buffer.-  mutable_buffer() noexcept-    : data_(0),-      size_(0)-  {-  }--  /// Construct a buffer to represent a given memory range.-  mutable_buffer(void* data, std::size_t size) noexcept-    : data_(data),-      size_(size)-  {-  }--  /// Construct a buffer from a span of bytes.-  template <template <typename, std::size_t> class Span,-      typename T, std::size_t Extent>-  mutable_buffer(const Span<T, Extent>& span,-      constraint_t<-        !is_const<T>::value,-        defaulted_constraint-      > = defaulted_constraint(),-      constraint_t<-        sizeof(T) == 1,-        defaulted_constraint-      > = defaulted_constraint(),-      constraint_t<-#if defined(ASIO_MSVC)-        detail::has_subspan_memfn<Span<T, Extent>>::value,-#else // defined(ASIO_MSVC)-        is_same<-          decltype(span.subspan(0, 0)),-          Span<T, static_cast<std::size_t>(-1)>-        >::value,-#endif // defined(ASIO_MSVC)-        defaulted_constraint-      > = defaulted_constraint())-    : data_(span.data()),-      size_(span.size())-  {-  }--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-  mutable_buffer(void* data, std::size_t size,-      asio::detail::function<void()> debug_check)-    : data_(data),-      size_(size),-      debug_check_(debug_check)-  {-  }--  const asio::detail::function<void()>& get_debug_check() const-  {-    return debug_check_;-  }-#endif // ASIO_ENABLE_BUFFER_DEBUGGING--  /// Get a pointer to the beginning of the memory range.-  void* data() const noexcept-  {-#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 noexcept-  {-    return size_;-  }--  /// Move the start of the buffer by the specified number of bytes.-  mutable_buffer& operator+=(std::size_t n) noexcept-  {-    std::size_t offset = n < size_ ? n : size_;-    data_ = static_cast<char*>(data_) + offset;-    size_ -= offset;-    return *this;-  }--private:-  void* data_;-  std::size_t size_;--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-  asio::detail::function<void()> debug_check_;-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-};--/// Holds a buffer that cannot be modified.-/**- * The const_buffer class provides a safe representation of a buffer that cannot- * be modified. It does not own the underlying data, and so is cheap to copy or- * assign.- *- * @par Accessing Buffer Contents- *- * 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 = b1.size();- * const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());- * @endcode- *- * The @c data() member function permits violations of type safety, so uses of- * it in application code should be carefully considered.- */-class const_buffer-{-public:-  /// Construct an empty buffer.-  const_buffer() noexcept-    : data_(0),-      size_(0)-  {-  }--  /// Construct a buffer to represent a given memory range.-  const_buffer(const void* data, std::size_t size) noexcept-    : data_(data),-      size_(size)-  {-  }--  /// Construct a non-modifiable buffer from a modifiable one.-  const_buffer(const mutable_buffer& b) noexcept-    : data_(b.data()),-      size_(b.size())-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , debug_check_(b.get_debug_check())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-  {-  }--  /// Construct a buffer from a span of bytes.-  template <template <typename, std::size_t> class Span,-      typename T, std::size_t Extent>-  const_buffer(const Span<T, Extent>& span,-      constraint_t<-        sizeof(T) == 1,-        defaulted_constraint-      > = defaulted_constraint(),-      constraint_t<-#if defined(ASIO_MSVC)-        detail::has_subspan_memfn<Span<T, Extent>>::value,-#else // defined(ASIO_MSVC)-        is_same<-          decltype(span.subspan(0, 0)),-          Span<T, static_cast<std::size_t>(-1)>-        >::value,-#endif // defined(ASIO_MSVC)-        defaulted_constraint-      > = defaulted_constraint())-    : data_(span.data()),-      size_(span.size())-  {-  }--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-  const_buffer(const void* data, std::size_t size,-      asio::detail::function<void()> debug_check)-    : data_(data),-      size_(size),-      debug_check_(debug_check)-  {-  }--  const asio::detail::function<void()>& get_debug_check() const-  {-    return debug_check_;-  }-#endif // ASIO_ENABLE_BUFFER_DEBUGGING--  /// Get a pointer to the beginning of the memory range.-  const void* data() const noexcept-  {-#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 noexcept-  {-    return size_;-  }--  /// Move the start of the buffer by the specified number of bytes.-  const_buffer& operator+=(std::size_t n) noexcept-  {-    std::size_t offset = n < size_ ? n : size_;-    data_ = static_cast<const char*>(data_) + offset;-    size_ -= offset;-    return *this;-  }--private:-  const void* data_;-  std::size_t size_;--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-  asio::detail::function<void()> debug_check_;-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-};--/// (Deprecated: Use the socket/descriptor wait() and async_wait() member-/// functions.) An implementation of both the ConstBufferSequence and-/// MutableBufferSequence concepts to represent a null buffer sequence.-class null_buffers-{-public:-  /// The type for each element in the list of buffers.-  typedef mutable_buffer value_type;--  /// A random-access iterator type that may be used to read elements.-  typedef const mutable_buffer* const_iterator;--  /// Get a random-access iterator to the first element.-  const_iterator begin() const noexcept-  {-    return &buf_;-  }--  /// Get a random-access iterator for one past the last element.-  const_iterator end() const noexcept-  {-    return &buf_;-  }--private:-  mutable_buffer buf_;-};--/** @defgroup buffer_sequence_begin asio::buffer_sequence_begin- *- * @brief The asio::buffer_sequence_begin function returns an iterator- * pointing to the first element in a buffer sequence.- */-/*@{*/--/// Get an iterator to the first element in a buffer sequence.-template <typename MutableBuffer>-inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,-    constraint_t<-      is_convertible<const MutableBuffer*, const mutable_buffer*>::value-    > = 0) noexcept-{-  return static_cast<const mutable_buffer*>(detail::addressof(b));-}--/// Get an iterator to the first element in a buffer sequence.-template <typename ConstBuffer>-inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,-    constraint_t<-      is_convertible<const ConstBuffer*, const const_buffer*>::value-    > = 0) noexcept-{-  return static_cast<const const_buffer*>(detail::addressof(b));-}--/// Get an iterator to the first element in a buffer sequence.-template <typename ConvertibleToBuffer>-inline const ConvertibleToBuffer* buffer_sequence_begin(-    const ConvertibleToBuffer& b,-    constraint_t<-      !is_convertible<const ConvertibleToBuffer*, const mutable_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<const ConvertibleToBuffer*, const const_buffer*>::value-    > = 0,-    constraint_t<-      is_convertible<ConvertibleToBuffer, mutable_buffer>::value-        || is_convertible<ConvertibleToBuffer, const_buffer>::value-    > = 0) noexcept-{-  return detail::addressof(b);-}--/// Get an iterator to the first element in a buffer sequence.-template <typename C>-inline auto buffer_sequence_begin(C& c,-    constraint_t<-      !is_convertible<const C*, const mutable_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<const C*, const const_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<C, mutable_buffer>::value-    > = 0,-    constraint_t<-      !is_convertible<C, const_buffer>::value-    > = 0) noexcept -> decltype(c.begin())-{-  return c.begin();-}--/// Get an iterator to the first element in a buffer sequence.-template <typename C>-inline auto buffer_sequence_begin(const C& c,-    constraint_t<-      !is_convertible<const C*, const mutable_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<const C*, const const_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<C, mutable_buffer>::value-    > = 0,-    constraint_t<-      !is_convertible<C, const_buffer>::value-    > = 0) noexcept -> decltype(c.begin())-{-  return c.begin();-}--/*@}*/--/** @defgroup buffer_sequence_end asio::buffer_sequence_end- *- * @brief The asio::buffer_sequence_end function returns an iterator- * pointing to one past the end element in a buffer sequence.- */-/*@{*/--/// Get an iterator to one past the end element in a buffer sequence.-template <typename MutableBuffer>-inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,-    constraint_t<-      is_convertible<const MutableBuffer*, const mutable_buffer*>::value-    > = 0) noexcept-{-  return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;-}--/// Get an iterator to one past the end element in a buffer sequence.-template <typename ConstBuffer>-inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,-    constraint_t<-      is_convertible<const ConstBuffer*, const const_buffer*>::value-    > = 0) noexcept-{-  return static_cast<const const_buffer*>(detail::addressof(b)) + 1;-}--/// Get an iterator to one past the end element in a buffer sequence.-template <typename ConvertibleToBuffer>-inline const ConvertibleToBuffer* buffer_sequence_end(-    const ConvertibleToBuffer& b,-    constraint_t<-      !is_convertible<const ConvertibleToBuffer*, const mutable_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<const ConvertibleToBuffer*, const const_buffer*>::value-    > = 0,-    constraint_t<-      is_convertible<ConvertibleToBuffer, mutable_buffer>::value-        || is_convertible<ConvertibleToBuffer, const_buffer>::value-    > = 0) noexcept-{-  return detail::addressof(b) + 1;-}--/// Get an iterator to one past the end element in a buffer sequence.-template <typename C>-inline auto buffer_sequence_end(C& c,-    constraint_t<-      !is_convertible<const C*, const mutable_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<const C*, const const_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<C, mutable_buffer>::value-    > = 0,-    constraint_t<-      !is_convertible<C, const_buffer>::value-    > = 0) noexcept -> decltype(c.end())-{-  return c.end();-}--/// Get an iterator to one past the end element in a buffer sequence.-template <typename C>-inline auto buffer_sequence_end(const C& c,-    constraint_t<-      !is_convertible<const C*, const mutable_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<const C*, const const_buffer*>::value-    > = 0,-    constraint_t<-      !is_convertible<C, mutable_buffer>::value-    > = 0,-    constraint_t<-      !is_convertible<C, const_buffer>::value-    > = 0) noexcept -> decltype(c.end())-{-  return c.end();-}--/*@}*/--namespace detail {--// Tag types used to select appropriately optimised overloads.-struct one_buffer {};-struct multiple_buffers {};--// Helper trait to detect single buffers.-template <typename BufferSequence>-struct buffer_sequence_cardinality :-  conditional_t<-    is_same<BufferSequence, mutable_buffer>::value-      || is_same<BufferSequence, const_buffer>::value,-    one_buffer, multiple_buffers> {};--template <typename Iterator>-inline std::size_t buffer_size(one_buffer,-    Iterator begin, Iterator) noexcept-{-  return const_buffer(*begin).size();-}--template <typename Iterator>-inline std::size_t buffer_size(multiple_buffers,-    Iterator begin, Iterator end) noexcept-{-  std::size_t total_buffer_size = 0;--  Iterator iter = begin;-  for (; iter != end; ++iter)-  {-    const_buffer b(*iter);-    total_buffer_size += b.size();-  }--  return total_buffer_size;-}--} // namespace detail--/// Get the total number of bytes in a buffer sequence.-/**- * The @c buffer_size function determines the total size of all buffers in the- * buffer sequence, as if computed as follows:- *- * @code size_t total_size = 0;- * auto i = asio::buffer_sequence_begin(buffers);- * auto end = asio::buffer_sequence_end(buffers);- * for (; i != end; ++i)- * {- *   const_buffer b(*i);- *   total_size += b.size();- * }- * return total_size; @endcode- *- * The @c BufferSequence template parameter may meet either of the @c- * ConstBufferSequence or @c MutableBufferSequence type requirements.- */-template <typename BufferSequence>-inline std::size_t buffer_size(const BufferSequence& b) noexcept-{-  return detail::buffer_size(-      detail::buffer_sequence_cardinality<BufferSequence>(),-      asio::buffer_sequence_begin(b),-      asio::buffer_sequence_end(b));-}--/// 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 n) noexcept-{-  std::size_t offset = n < b.size() ? n : b.size();-  char* new_data = static_cast<char*>(b.data()) + offset;-  std::size_t new_size = b.size() - offset;-  return mutable_buffer(new_data, new_size-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , b.get_debug_check()-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new modifiable buffer that is offset from the start of another.-/**- * @relates mutable_buffer- */-inline mutable_buffer operator+(std::size_t n,-    const mutable_buffer& b) noexcept-{-  return b + n;-}--/// Create a new non-modifiable buffer that is offset from the start of another.-/**- * @relates const_buffer- */-inline const_buffer operator+(const const_buffer& b,-    std::size_t n) noexcept-{-  std::size_t offset = n < b.size() ? n : b.size();-  const char* new_data = static_cast<const char*>(b.data()) + offset;-  std::size_t new_size = b.size() - offset;-  return const_buffer(new_data, new_size-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , b.get_debug_check()-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new non-modifiable buffer that is offset from the start of another.-/**- * @relates const_buffer- */-inline const_buffer operator+(std::size_t n,-    const const_buffer& b) noexcept-{-  return b + n;-}--#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-namespace detail {--template <typename Iterator>-class buffer_debug_check-{-public:-  buffer_debug_check(Iterator iter)-    : iter_(iter)-  {-  }--  ~buffer_debug_check()-  {-#if defined(ASIO_MSVC) && (ASIO_MSVC == 1400)-    // MSVC 8's string iterator checking may crash in a std::string::iterator-    // object's destructor when the iterator points to an already-destroyed-    // std::string object, unless the iterator is cleared first.-    iter_ = Iterator();-#endif // defined(ASIO_MSVC) && (ASIO_MSVC == 1400)-  }--  void operator()()-  {-    (void)*iter_;-  }--private:-  Iterator iter_;-};--} // namespace detail-#endif // ASIO_ENABLE_BUFFER_DEBUGGING--/** @defgroup buffer asio::buffer- *- * @brief The asio::buffer function is used to create a buffer object to- * represent raw memory, an array of POD elements, a vector of POD elements,- * or a std::string.- *- * A buffer object represents a contiguous region of memory as a 2-tuple- * consisting of a pointer and size in bytes. A tuple of the form <tt>{void*,- * size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a- * tuple of the form <tt>{const void*, size_t}</tt> specifies a const- * (non-modifiable) region of memory. These two forms correspond to the classes- * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion- * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the- * opposite conversion is not permitted.- *- * The simplest use case involves reading or writing a single buffer of a- * specified size:- *- * @code sock.send(asio::buffer(data, size)); @endcode- *- * In the above example, the return value of asio::buffer meets the- * requirements of the ConstBufferSequence concept so that it may be directly- * passed to the socket's write function. A buffer created for modifiable- * memory also meets the requirements of the MutableBufferSequence concept.- *- * An individual buffer may be created from a builtin array, std::vector,- * std::array or boost::array of POD elements. This helps prevent buffer- * overruns by automatically determining the size of the buffer:- *- * @code char d1[128];- * size_t bytes_transferred = sock.receive(asio::buffer(d1));- *- * std::vector<char> d2(128);- * bytes_transferred = sock.receive(asio::buffer(d2));- *- * std::array<char, 128> d3;- * bytes_transferred = sock.receive(asio::buffer(d3));- *- * boost::array<char, 128> d4;- * bytes_transferred = sock.receive(asio::buffer(d4)); @endcode- *- * In all three cases above, the buffers created are exactly 128 bytes long.- * Note that a vector is @e never automatically resized when creating or using- * a buffer. The buffer size is determined using the vector's <tt>size()</tt>- * member function, and not its capacity.- *- * @par Accessing Buffer Contents- *- * 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 = b1.size();- * unsigned char* p1 = static_cast<unsigned char*>(b1.data());- *- * asio::const_buffer b2 = ...;- * std::size_t s2 = b2.size();- * const void* p2 = b2.data(); @endcode- *- * The @c data() member function permits violations of type safety, so- * uses of it in application code should be carefully considered.- *- * 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- *- * The @ref buffer_copy function may be used to copy raw bytes between- * individual buffers and buffer sequences.-*- * In particular, when used with the @ref buffer_size function, the @ref- * buffer_copy function can be used to linearise a sequence of buffers. For- * example:- *- * @code vector<const_buffer> buffers = ...;- *- * vector<unsigned char> data(asio::buffer_size(buffers));- * asio::buffer_copy(asio::buffer(data), buffers); @endcode- *- * Note that @ref buffer_copy is implemented in terms of @c memcpy, and- * consequently it cannot be used to copy between overlapping memory regions.- *- * @par Buffer Invalidation- *- * A buffer object does not have any ownership of the memory it refers to. It- * is the responsibility of the application to ensure the memory region remains- * valid until it is no longer required for an I/O operation. When the memory- * is no longer available, the buffer is said to have been invalidated.- *- * For the asio::buffer overloads that accept an argument of type- * std::vector, the buffer objects returned are invalidated by any vector- * operation that also invalidates all references, pointers and iterators- * referring to the elements in the sequence (C++ Std, 23.2.4)- *- * For the asio::buffer overloads that accept an argument of type- * std::basic_string, the buffer objects returned are invalidated according to- * the rules defined for invalidation of references, pointers and iterators- * referring to elements of the sequence (C++ Std, 21.3).- *- * @par Buffer Arithmetic- *- * Buffer objects may be manipulated using simple arithmetic in a safe way- * which helps prevent buffer overruns. Consider an array initialised as- * follows:- *- * @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode- *- * A buffer object @c b1 created using:- *- * @code b1 = asio::buffer(a); @endcode- *- * represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An- * optional second argument to the asio::buffer function may be used to- * limit the size, in bytes, of the buffer:- *- * @code b2 = asio::buffer(a, 3); @endcode- *- * such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the- * size argument exceeds the actual size of the array, the size of the buffer- * object created will be limited to the array size.- *- * An offset may be applied to an existing buffer to create a new one:- *- * @code b3 = b1 + 2; @endcode- *- * where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset- * exceeds the size of the existing buffer, the newly created buffer will be- * empty.- *- * Both an offset and size may be specified to create a buffer that corresponds- * to a specific range of bytes within an existing buffer:- *- * @code b4 = asio::buffer(b1 + 1, 3); @endcode- *- * so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>.- *- * @par Buffers and Scatter-Gather I/O- *- * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple- * buffer objects may be assigned into a container that supports the- * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:- *- * @code- * char d1[128];- * std::vector<char> d2(128);- * boost::array<char, 128> d3;- *- * boost::array<mutable_buffer, 3> bufs1 = {- *   asio::buffer(d1),- *   asio::buffer(d2),- *   asio::buffer(d3) };- * bytes_transferred = sock.receive(bufs1);- *- * std::vector<const_buffer> bufs2;- * bufs2.push_back(asio::buffer(d1));- * bufs2.push_back(asio::buffer(d2));- * bufs2.push_back(asio::buffer(d3));- * bytes_transferred = sock.send(bufs2); @endcode- *- * @par Buffer Literals- *- * The `_buf` literal suffix, defined in namespace- * <tt>asio::buffer_literals</tt>, may be used to create @c const_buffer- * objects from string, binary integer, and hexadecimal integer literals.- * For example:- *- * @code- * using namespace asio::buffer_literals;- *- * asio::const_buffer b1 = "hello"_buf;- * asio::const_buffer b2 = 0xdeadbeef_buf;- * asio::const_buffer b3 = 0x0123456789abcdef0123456789abcdef_buf;- * asio::const_buffer b4 = 0b1010101011001100_buf; @endcode- *- * Note that the memory associated with a buffer literal is valid for the- * lifetime of the program. This means that the buffer can be safely used with- * asynchronous operations.- */-/*@{*/--/// Create a new modifiable buffer from an existing buffer.-/**- * @returns <tt>mutable_buffer(b)</tt>.- */-ASIO_NODISCARD inline mutable_buffer buffer(-    const mutable_buffer& b) noexcept-{-  return mutable_buffer(b);-}--/// Create a new modifiable buffer from an existing buffer.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     b.data(),- *     min(b.size(), max_size_in_bytes)); @endcode- */-ASIO_NODISCARD inline mutable_buffer buffer(-    const mutable_buffer& b,-    std::size_t max_size_in_bytes) noexcept-{-  return mutable_buffer(-      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-        ));-}--/// Create a new non-modifiable buffer from an existing buffer.-/**- * @returns <tt>const_buffer(b)</tt>.- */-ASIO_NODISCARD inline const_buffer buffer(-    const const_buffer& b) noexcept-{-  return const_buffer(b);-}--/// Create a new non-modifiable buffer from an existing buffer.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     b.data(),- *     min(b.size(), max_size_in_bytes)); @endcode- */-ASIO_NODISCARD inline const_buffer buffer(-    const const_buffer& b,-    std::size_t max_size_in_bytes) noexcept-{-  return 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-      );-}--/// Create a new modifiable buffer that represents the given memory range.-/**- * @returns <tt>mutable_buffer(data, size_in_bytes)</tt>.- */-ASIO_NODISCARD inline mutable_buffer buffer(-    void* data, std::size_t size_in_bytes) noexcept-{-  return mutable_buffer(data, size_in_bytes);-}--/// Create a new non-modifiable buffer that represents the given memory range.-/**- * @returns <tt>const_buffer(data, size_in_bytes)</tt>.- */-ASIO_NODISCARD inline const_buffer buffer(-    const void* data, std::size_t size_in_bytes) noexcept-{-  return const_buffer(data, size_in_bytes);-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     static_cast<void*>(data),- *     N * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline mutable_buffer buffer(-    PodType (&data)[N]) noexcept-{-  return mutable_buffer(data, N * sizeof(PodType));-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     static_cast<void*>(data),- *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline mutable_buffer buffer(-    PodType (&data)[N],-    std::size_t max_size_in_bytes) noexcept-{-  return mutable_buffer(data,-      N * sizeof(PodType) < max_size_in_bytes-      ? N * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     static_cast<const void*>(data),- *     N * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    const PodType (&data)[N]) noexcept-{-  return const_buffer(data, N * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     static_cast<const void*>(data),- *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    const PodType (&data)[N],-    std::size_t max_size_in_bytes) noexcept-{-  return const_buffer(data,-      N * sizeof(PodType) < max_size_in_bytes-      ? N * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.data(),- *     data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline mutable_buffer buffer(-    boost::array<PodType, N>& data) noexcept-{-  return mutable_buffer(-      data.c_array(), data.size() * sizeof(PodType));-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.data(),- *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline mutable_buffer buffer(-    boost::array<PodType, N>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return mutable_buffer(data.c_array(),-      data.size() * sizeof(PodType) < max_size_in_bytes-      ? data.size() * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.data(),- *     data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    boost::array<const PodType, N>& data) noexcept-{-  return const_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.data(),- *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    boost::array<const PodType, N>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return const_buffer(data.data(),-      data.size() * sizeof(PodType) < max_size_in_bytes-      ? data.size() * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.data(),- *     data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    const boost::array<PodType, N>& data) noexcept-{-  return const_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.data(),- *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    const boost::array<PodType, N>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return const_buffer(data.data(),-      data.size() * sizeof(PodType) < max_size_in_bytes-      ? data.size() * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.data(),- *     data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline mutable_buffer buffer(-    std::array<PodType, N>& data) noexcept-{-  return mutable_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new modifiable buffer that represents the given POD array.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.data(),- *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline mutable_buffer buffer(-    std::array<PodType, N>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return mutable_buffer(data.data(),-      data.size() * sizeof(PodType) < max_size_in_bytes-      ? data.size() * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.data(),- *     data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    std::array<const PodType, N>& data) noexcept-{-  return const_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.data(),- *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    std::array<const PodType, N>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return const_buffer(data.data(),-      data.size() * sizeof(PodType) < max_size_in_bytes-      ? data.size() * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.data(),- *     data.size() * sizeof(PodType)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    const std::array<PodType, N>& data) noexcept-{-  return const_buffer(data.data(), data.size() * sizeof(PodType));-}--/// Create a new non-modifiable buffer that represents the given POD array.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.data(),- *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode- */-template <typename PodType, std::size_t N>-ASIO_NODISCARD inline const_buffer buffer(-    const std::array<PodType, N>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return const_buffer(data.data(),-      data.size() * sizeof(PodType) < max_size_in_bytes-      ? data.size() * sizeof(PodType) : max_size_in_bytes);-}--/// Create a new modifiable buffer that represents the given POD vector.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.size() ? &data[0] : 0,- *     data.size() * sizeof(PodType)); @endcode- *- * @note The buffer is invalidated by any vector operation that would also- * invalidate iterators.- */-template <typename PodType, typename Allocator>-ASIO_NODISCARD inline mutable_buffer buffer(-    std::vector<PodType, Allocator>& data) noexcept-{-  return mutable_buffer(-      data.size() ? &data[0] : 0, data.size() * sizeof(PodType)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename std::vector<PodType, Allocator>::iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new modifiable buffer that represents the given POD vector.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.size() ? &data[0] : 0,- *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode- *- * @note The buffer is invalidated by any vector operation that would also- * invalidate iterators.- */-template <typename PodType, typename Allocator>-ASIO_NODISCARD inline mutable_buffer buffer(-    std::vector<PodType, Allocator>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return mutable_buffer(data.size() ? &data[0] : 0,-      data.size() * sizeof(PodType) < max_size_in_bytes-      ? data.size() * sizeof(PodType) : max_size_in_bytes-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename std::vector<PodType, Allocator>::iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new non-modifiable buffer that represents the given POD vector.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.size() ? &data[0] : 0,- *     data.size() * sizeof(PodType)); @endcode- *- * @note The buffer is invalidated by any vector operation that would also- * invalidate iterators.- */-template <typename PodType, typename Allocator>-ASIO_NODISCARD inline const_buffer buffer(-    const std::vector<PodType, Allocator>& data) noexcept-{-  return const_buffer(-      data.size() ? &data[0] : 0, data.size() * sizeof(PodType)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename std::vector<PodType, Allocator>::const_iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new non-modifiable buffer that represents the given POD vector.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.size() ? &data[0] : 0,- *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode- *- * @note The buffer is invalidated by any vector operation that would also- * invalidate iterators.- */-template <typename PodType, typename Allocator>-ASIO_NODISCARD inline const_buffer buffer(-    const std::vector<PodType, Allocator>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return const_buffer(data.size() ? &data[0] : 0,-      data.size() * sizeof(PodType) < max_size_in_bytes-      ? data.size() * sizeof(PodType) : max_size_in_bytes-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename std::vector<PodType, Allocator>::const_iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new modifiable buffer that represents the given string.-/**- * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,- * data.size() * sizeof(Elem))</tt>.- *- * @note The buffer is invalidated by any non-const operation called on the- * given string object.- */-template <typename Elem, typename Traits, typename Allocator>-ASIO_NODISCARD inline mutable_buffer buffer(-    std::basic_string<Elem, Traits, Allocator>& data) noexcept-{-  return mutable_buffer(data.size() ? &data[0] : 0,-      data.size() * sizeof(Elem)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename std::basic_string<Elem, Traits, Allocator>::iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new modifiable buffer that represents the given string.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.size() ? &data[0] : 0,- *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode- *- * @note The buffer is invalidated by any non-const operation called on the- * given string object.- */-template <typename Elem, typename Traits, typename Allocator>-ASIO_NODISCARD inline mutable_buffer buffer(-    std::basic_string<Elem, Traits, Allocator>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return mutable_buffer(data.size() ? &data[0] : 0,-      data.size() * sizeof(Elem) < max_size_in_bytes-      ? data.size() * sizeof(Elem) : max_size_in_bytes-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename std::basic_string<Elem, Traits, Allocator>::iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new non-modifiable buffer that represents the given string.-/**- * @returns <tt>const_buffer(data.data(), data.size() * sizeof(Elem))</tt>.- *- * @note The buffer is invalidated by any non-const operation called on the- * given string object.- */-template <typename Elem, typename Traits, typename Allocator>-ASIO_NODISCARD inline const_buffer buffer(-    const std::basic_string<Elem, Traits, Allocator>& data) noexcept-{-  return const_buffer(data.data(), data.size() * sizeof(Elem)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename std::basic_string<Elem, Traits, Allocator>::const_iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new non-modifiable buffer that represents the given string.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.data(),- *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode- *- * @note The buffer is invalidated by any non-const operation called on the- * given string object.- */-template <typename Elem, typename Traits, typename Allocator>-ASIO_NODISCARD inline const_buffer buffer(-    const std::basic_string<Elem, Traits, Allocator>& data,-    std::size_t max_size_in_bytes) noexcept-{-  return const_buffer(data.data(),-      data.size() * sizeof(Elem) < max_size_in_bytes-      ? data.size() * sizeof(Elem) : max_size_in_bytes-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename std::basic_string<Elem, Traits, Allocator>::const_iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--#if defined(ASIO_HAS_STRING_VIEW) \-  || defined(GENERATING_DOCUMENTATION)--/// Create a new non-modifiable buffer that represents the given string_view.-/**- * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,- * data.size() * sizeof(Elem))</tt>.- */-template <typename Elem, typename Traits>-ASIO_NODISCARD inline const_buffer buffer(-    basic_string_view<Elem, Traits> data) noexcept-{-  return const_buffer(data.size() ? &data[0] : 0,-      data.size() * sizeof(Elem)-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename basic_string_view<Elem, Traits>::iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--/// Create a new non-modifiable buffer that represents the given string.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.size() ? &data[0] : 0,- *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode- */-template <typename Elem, typename Traits>-ASIO_NODISCARD inline const_buffer buffer(-    basic_string_view<Elem, Traits> data,-    std::size_t max_size_in_bytes) noexcept-{-  return const_buffer(data.size() ? &data[0] : 0,-      data.size() * sizeof(Elem) < max_size_in_bytes-      ? data.size() * sizeof(Elem) : max_size_in_bytes-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)-      , detail::buffer_debug_check<-          typename basic_string_view<Elem, Traits>::iterator-        >(data.begin())-#endif // ASIO_ENABLE_BUFFER_DEBUGGING-      );-}--#endif // defined(ASIO_HAS_STRING_VIEW)-       //  || defined(GENERATING_DOCUMENTATION)--/// Create a new modifiable buffer from a contiguous container.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.size() ? &data[0] : 0,- *     data.size() * sizeof(typename T::value_type)); @endcode- */-template <typename T>-ASIO_NODISCARD inline mutable_buffer buffer(-    T& data,-    constraint_t<-      is_contiguous_iterator<typename T::iterator>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, const_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, mutable_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_const<-        remove_reference_t<-          typename std::iterator_traits<typename T::iterator>::reference-        >-      >::value,-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return mutable_buffer(-      data.size() ? detail::to_address(data.begin()) : 0,-      data.size() * sizeof(typename T::value_type));-}--/// Create a new modifiable buffer from a contiguous container.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer(- *     data.size() ? &data[0] : 0,- *     min(- *       data.size() * sizeof(typename T::value_type),- *       max_size_in_bytes)); @endcode- */-template <typename T>-ASIO_NODISCARD inline mutable_buffer buffer(-    T& data, std::size_t max_size_in_bytes,-    constraint_t<-      is_contiguous_iterator<typename T::iterator>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, const_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, mutable_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_const<-        remove_reference_t<-          typename std::iterator_traits<typename T::iterator>::reference-        >-      >::value,-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return mutable_buffer(-      data.size() ? detail::to_address(data.begin()) : 0,-      data.size() * sizeof(typename T::value_type) < max_size_in_bytes-      ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);-}--/// Create a new non-modifiable buffer from a contiguous container.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.size() ? &data[0] : 0,- *     data.size() * sizeof(typename T::value_type)); @endcode- */-template <typename T>-ASIO_NODISCARD inline const_buffer buffer(-    T& data,-    constraint_t<-      is_contiguous_iterator<typename T::iterator>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, const_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, mutable_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      is_const<-        remove_reference_t<-          typename std::iterator_traits<typename T::iterator>::reference-        >-      >::value,-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return const_buffer(-      data.size() ? detail::to_address(data.begin()) : 0,-      data.size() * sizeof(typename T::value_type));-}--/// Create a new non-modifiable buffer from a contiguous container.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.size() ? &data[0] : 0,- *     min(- *       data.size() * sizeof(typename T::value_type),- *       max_size_in_bytes)); @endcode- */-template <typename T>-ASIO_NODISCARD inline const_buffer buffer(-    T& data, std::size_t max_size_in_bytes,-    constraint_t<-      is_contiguous_iterator<typename T::iterator>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, const_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, mutable_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      is_const<-        remove_reference_t<-          typename std::iterator_traits<typename T::iterator>::reference-        >-      >::value,-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return const_buffer(-      data.size() ? detail::to_address(data.begin()) : 0,-      data.size() * sizeof(typename T::value_type) < max_size_in_bytes-      ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);-}--/// Create a new non-modifiable buffer from a contiguous container.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.size() ? &data[0] : 0,- *     data.size() * sizeof(typename T::value_type)); @endcode- */-template <typename T>-ASIO_NODISCARD inline const_buffer buffer(-    const T& data,-    constraint_t<-      is_contiguous_iterator<typename T::const_iterator>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, const_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, mutable_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return const_buffer(-      data.size() ? detail::to_address(data.begin()) : 0,-      data.size() * sizeof(typename T::value_type));-}--/// Create a new non-modifiable buffer from a contiguous container.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer(- *     data.size() ? &data[0] : 0,- *     min(- *       data.size() * sizeof(typename T::value_type),- *       max_size_in_bytes)); @endcode- */-template <typename T>-ASIO_NODISCARD inline const_buffer buffer(-    const T& data, std::size_t max_size_in_bytes,-    constraint_t<-      is_contiguous_iterator<typename T::const_iterator>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, const_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      !is_convertible<T, mutable_buffer>::value,-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return const_buffer(-      data.size() ? detail::to_address(data.begin()) : 0,-      data.size() * sizeof(typename T::value_type) < max_size_in_bytes-      ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);-}--/// Create a new modifiable buffer from a span.-/**- * @returns <tt>mutable_buffer(span)</tt>.- */-template <template <typename, std::size_t> class Span,-    typename T, std::size_t Extent>-ASIO_NODISCARD inline mutable_buffer buffer(-    const Span<T, Extent>& span,-    constraint_t<-      !is_const<T>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      sizeof(T) == 1,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-#if defined(ASIO_MSVC)-      detail::has_subspan_memfn<Span<T, Extent>>::value,-#else // defined(ASIO_MSVC)-      is_same<-        decltype(span.subspan(0, 0)),-        Span<T, static_cast<std::size_t>(-1)>-      >::value,-#endif // defined(ASIO_MSVC)-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return mutable_buffer(span);-}--/// Create a new modifiable buffer from a span.-/**- * @returns A mutable_buffer value equivalent to:- * @code mutable_buffer b(span);- * mutable_buffer(- *     b.data(),- *     min(b.size(), max_size_in_bytes)); @endcode- */-template <template <typename, std::size_t> class Span,-    typename T, std::size_t Extent>-ASIO_NODISCARD inline mutable_buffer buffer(-    const Span<T, Extent>& span,-    std::size_t max_size_in_bytes,-    constraint_t<-      !is_const<T>::value,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-      sizeof(T) == 1,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-#if defined(ASIO_MSVC)-      detail::has_subspan_memfn<Span<T, Extent>>::value,-#else // defined(ASIO_MSVC)-      is_same<-        decltype(span.subspan(0, 0)),-        Span<T, static_cast<std::size_t>(-1)>-      >::value,-#endif // defined(ASIO_MSVC)-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return buffer(mutable_buffer(span), max_size_in_bytes);-}--/// Create a new non-modifiable buffer from a span.-/**- * @returns <tt>const_buffer(span)</tt>.- */-template <template <typename, std::size_t> class Span,-    typename T, std::size_t Extent>-ASIO_NODISCARD inline const_buffer buffer(-    const Span<const T, Extent>& span,-    constraint_t<-      sizeof(T) == 1,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-#if defined(ASIO_MSVC)-      detail::has_subspan_memfn<Span<const T, Extent>>::value,-#else // defined(ASIO_MSVC)-      is_same<-        decltype(span.subspan(0, 0)),-        Span<T, static_cast<std::size_t>(-1)>-      >::value,-#endif // defined(ASIO_MSVC)-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return const_buffer(span);-}--/// Create a new non-modifiable buffer from a span.-/**- * @returns A const_buffer value equivalent to:- * @code const_buffer b1(b);- * const_buffer(- *     b1.data(),- *     min(b1.size(), max_size_in_bytes)); @endcode- */-template <template <typename, std::size_t> class Span,-    typename T, std::size_t Extent>-ASIO_NODISCARD inline const_buffer buffer(-    const Span<const T, Extent>& span,-    std::size_t max_size_in_bytes,-    constraint_t<-      sizeof(T) == 1,-      defaulted_constraint-    > = defaulted_constraint(),-    constraint_t<-#if defined(ASIO_MSVC)-      detail::has_subspan_memfn<Span<const T, Extent>>::value,-#else // defined(ASIO_MSVC)-      is_same<-        decltype(span.subspan(0, 0)),-        Span<T, static_cast<std::size_t>(-1)>-      >::value,-#endif // defined(ASIO_MSVC)-      defaulted_constraint-    > = defaulted_constraint()) noexcept-{-  return buffer(const_buffer(span), max_size_in_bytes);-}--/*@}*/--/// Adapt a basic_string to the DynamicBuffer requirements.-/**- * Requires that <tt>sizeof(Elem) == 1</tt>.- */-template <typename Elem, typename Traits, typename Allocator>-class dynamic_string_buffer-{-public:-  /// The type used to represent a sequence of constant buffers that refers to-  /// the underlying memory.-  typedef const_buffer const_buffers_type;--  /// The type used to represent a sequence of mutable buffers that refers to-  /// the underlying memory.-  typedef mutable_buffer mutable_buffers_type;--  /// Construct a dynamic buffer from a string.-  /**-   * @param s The string to be used as backing storage for the dynamic buffer.-   * The object stores a reference to the string and the user is responsible-   * for ensuring that the string object remains valid while the-   * dynamic_string_buffer object, and copies of the object, are in use.-   *-   * @b DynamicBuffer_v1: Any existing data in the string is treated as the-   * dynamic buffer's input sequence.-   *-   * @param maximum_size Specifies a maximum size for the buffer, in bytes.-   */-  explicit dynamic_string_buffer(std::basic_string<Elem, Traits, Allocator>& s,-      std::size_t maximum_size =-        (std::numeric_limits<std::size_t>::max)()) noexcept-    : string_(s),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      size_((std::numeric_limits<std::size_t>::max)()),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      max_size_(maximum_size)-  {-  }--  /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.-  dynamic_string_buffer(const dynamic_string_buffer& other) noexcept-    : string_(other.string_),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      size_(other.size_),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      max_size_(other.max_size_)-  {-  }--  /// Move construct a dynamic buffer.-  dynamic_string_buffer(dynamic_string_buffer&& other) noexcept-    : string_(other.string_),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      size_(other.size_),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      max_size_(other.max_size_)-  {-  }--  /// @b DynamicBuffer_v1: Get the size of the input sequence.-  /// @b DynamicBuffer_v2: Get the current size of the underlying memory.-  /**-   * @returns @b DynamicBuffer_v1 The current size of the input sequence.-   * @b DynamicBuffer_v2: The current size of the underlying string if less than-   * max_size(). Otherwise returns max_size().-   */-  std::size_t size() const noexcept-  {-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-    if (size_ != (std::numeric_limits<std::size_t>::max)())-      return size_;-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-    return (std::min)(string_.size(), max_size());-  }--  /// Get the maximum size of the dynamic buffer.-  /**-   * @returns The allowed maximum size of the underlying memory.-   */-  std::size_t max_size() const noexcept-  {-    return max_size_;-  }--  /// Get the maximum size that the buffer may grow to without triggering-  /// reallocation.-  /**-   * @returns The current capacity of the underlying string if less than-   * max_size(). Otherwise returns max_size().-   */-  std::size_t capacity() const noexcept-  {-    return (std::min)(string_.capacity(), max_size());-  }--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  /// @b DynamicBuffer_v1: Get a list of buffers that represents the input-  /// sequence.-  /**-   * @returns An object of type @c const_buffers_type that satisfies-   * ConstBufferSequence requirements, representing the basic_string memory in-   * the input sequence.-   *-   * @note The returned object is invalidated by any @c dynamic_string_buffer-   * or @c basic_string member function that resizes or erases the string.-   */-  const_buffers_type data() const noexcept-  {-    return const_buffers_type(asio::buffer(string_, size_));-  }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--  /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the-  /// underlying memory.-  /**-   * @param pos Position of the first byte to represent in the buffer sequence-   *-   * @param n The number of bytes to return in the buffer sequence. If the-   * underlying memory is shorter, the buffer sequence represents as many bytes-   * as are available.-   *-   * @returns An object of type @c mutable_buffers_type that satisfies-   * MutableBufferSequence requirements, representing the basic_string memory.-   *-   * @note The returned object is invalidated by any @c dynamic_string_buffer-   * or @c basic_string member function that resizes or erases the string.-   */-  mutable_buffers_type data(std::size_t pos, std::size_t n) noexcept-  {-    return mutable_buffers_type(asio::buffer(-          asio::buffer(string_, max_size_) + pos, n));-  }--  /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the-  /// underlying memory.-  /**-   * @param pos Position of the first byte to represent in the buffer sequence-   *-   * @param n The number of bytes to return in the buffer sequence. If the-   * underlying memory is shorter, the buffer sequence represents as many bytes-   * as are available.-   *-   * @note The returned object is invalidated by any @c dynamic_string_buffer-   * or @c basic_string member function that resizes or erases the string.-   */-  const_buffers_type data(std::size_t pos,-      std::size_t n) const noexcept-  {-    return const_buffers_type(asio::buffer(-          asio::buffer(string_, max_size_) + pos, n));-  }--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  /// @b DynamicBuffer_v1: Get a list of buffers that represents the output-  /// sequence, with the given size.-  /**-   * Ensures that the output sequence can accommodate @c n bytes, resizing the-   * basic_string object as necessary.-   *-   * @returns An object of type @c mutable_buffers_type that satisfies-   * MutableBufferSequence requirements, representing basic_string memory-   * at the start of the output sequence of size @c n.-   *-   * @throws std::length_error If <tt>size() + n > max_size()</tt>.-   *-   * @note The returned object is invalidated by any @c dynamic_string_buffer-   * or @c basic_string member function that modifies the input sequence or-   * output sequence.-   */-  mutable_buffers_type prepare(std::size_t n)-  {-    if (size() > max_size() || max_size() - size() < n)-    {-      std::length_error ex("dynamic_string_buffer too long");-      asio::detail::throw_exception(ex);-    }--    if (size_ == (std::numeric_limits<std::size_t>::max)())-      size_ = string_.size(); // Enable v1 behaviour.--    string_.resize(size_ + n);--    return asio::buffer(asio::buffer(string_) + size_, n);-  }--  /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input-  /// sequence.-  /**-   * @param n The number of bytes to append from the start of the output-   * sequence to the end of the input sequence. The remainder of the output-   * sequence is discarded.-   *-   * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and-   * no intervening operations that modify the input or output sequence.-   *-   * @note If @c n is greater than the size of the output sequence, the entire-   * output sequence is moved to the input sequence and no error is issued.-   */-  void commit(std::size_t n)-  {-    size_ += (std::min)(n, string_.size() - size_);-    string_.resize(size_);-  }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--  /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of-  /// bytes.-  /**-   * Resizes the string to accommodate an additional @c n bytes at the end.-   *-   * @throws std::length_error If <tt>size() + n > max_size()</tt>.-   */-  void grow(std::size_t n)-  {-    if (size() > max_size() || max_size() - size() < n)-    {-      std::length_error ex("dynamic_string_buffer too long");-      asio::detail::throw_exception(ex);-    }--    string_.resize(size() + n);-  }--  /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number-  /// of bytes.-  /**-   * Erases @c n bytes from the end of the string by resizing the basic_string-   * object. If @c n is greater than the current size of the string, the string-   * is emptied.-   */-  void shrink(std::size_t n)-  {-    string_.resize(n > size() ? 0 : size() - n);-  }--  /// @b DynamicBuffer_v1: Remove characters from the input sequence.-  /// @b DynamicBuffer_v2: Consume the specified number of bytes from the-  /// beginning of the underlying memory.-  /**-   * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the-   * input sequence. @note If @c n is greater than the size of the input-   * sequence, the entire input sequence is consumed and no error is issued.-   *-   * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the string.-   * If @c n is greater than the current size of the string, the string is-   * emptied.-   */-  void consume(std::size_t n)-  {-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-    if (size_ != (std::numeric_limits<std::size_t>::max)())-    {-      std::size_t consume_length = (std::min)(n, size_);-      string_.erase(0, consume_length);-      size_ -= consume_length;-      return;-    }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-    string_.erase(0, n);-  }--private:-  std::basic_string<Elem, Traits, Allocator>& string_;-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  std::size_t size_;-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  const std::size_t max_size_;-};--/// Adapt a vector to the DynamicBuffer requirements.-/**- * Requires that <tt>sizeof(Elem) == 1</tt>.- */-template <typename Elem, typename Allocator>-class dynamic_vector_buffer-{-public:-  /// The type used to represent a sequence of constant buffers that refers to-  /// the underlying memory.-  typedef const_buffer const_buffers_type;--  /// The type used to represent a sequence of mutable buffers that refers to-  /// the underlying memory.-  typedef mutable_buffer mutable_buffers_type;--  /// Construct a dynamic buffer from a vector.-  /**-   * @param v The vector to be used as backing storage for the dynamic buffer.-   * The object stores a reference to the vector and the user is responsible-   * for ensuring that the vector object remains valid while the-   * dynamic_vector_buffer object, and copies of the object, are in use.-   *-   * @param maximum_size Specifies a maximum size for the buffer, in bytes.-   */-  explicit dynamic_vector_buffer(std::vector<Elem, Allocator>& v,-      std::size_t maximum_size =-        (std::numeric_limits<std::size_t>::max)()) noexcept-    : vector_(v),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      size_((std::numeric_limits<std::size_t>::max)()),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      max_size_(maximum_size)-  {-  }--  /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.-  dynamic_vector_buffer(const dynamic_vector_buffer& other) noexcept-    : vector_(other.vector_),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      size_(other.size_),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      max_size_(other.max_size_)-  {-  }--  /// Move construct a dynamic buffer.-  dynamic_vector_buffer(dynamic_vector_buffer&& other) noexcept-    : vector_(other.vector_),-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      size_(other.size_),-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-      max_size_(other.max_size_)-  {-  }--  /// @b DynamicBuffer_v1: Get the size of the input sequence.-  /// @b DynamicBuffer_v2: Get the current size of the underlying memory.-  /**-   * @returns @b DynamicBuffer_v1 The current size of the input sequence.-   * @b DynamicBuffer_v2: The current size of the underlying vector if less than-   * max_size(). Otherwise returns max_size().-   */-  std::size_t size() const noexcept-  {-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-    if (size_ != (std::numeric_limits<std::size_t>::max)())-      return size_;-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-    return (std::min)(vector_.size(), max_size());-  }--  /// Get the maximum size of the dynamic buffer.-  /**-   * @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes-   * of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed-   * maximum size of the underlying memory.-   */-  std::size_t max_size() const noexcept-  {-    return max_size_;-  }--  /// Get the maximum size that the buffer may grow to without triggering-  /// reallocation.-  /**-   * @returns @b DynamicBuffer_v1: The current total capacity of the buffer,-   * i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2:-   * The current capacity of the underlying vector if less than max_size().-   * Otherwise returns max_size().-   */-  std::size_t capacity() const noexcept-  {-    return (std::min)(vector_.capacity(), max_size());-  }--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  /// @b DynamicBuffer_v1: Get a list of buffers that represents the input-  /// sequence.-  /**-   * @returns An object of type @c const_buffers_type that satisfies-   * ConstBufferSequence requirements, representing the vector memory in the-   * input sequence.-   *-   * @note The returned object is invalidated by any @c dynamic_vector_buffer-   * or @c vector member function that modifies the input sequence or output-   * sequence.-   */-  const_buffers_type data() const noexcept-  {-    return const_buffers_type(asio::buffer(vector_, size_));-  }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--  /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the-  /// underlying memory.-  /**-   * @param pos Position of the first byte to represent in the buffer sequence-   *-   * @param n The number of bytes to return in the buffer sequence. If the-   * underlying memory is shorter, the buffer sequence represents as many bytes-   * as are available.-   *-   * @returns An object of type @c mutable_buffers_type that satisfies-   * MutableBufferSequence requirements, representing the vector memory.-   *-   * @note The returned object is invalidated by any @c dynamic_vector_buffer-   * or @c vector member function that resizes or erases the vector.-   */-  mutable_buffers_type data(std::size_t pos, std::size_t n) noexcept-  {-    return mutable_buffers_type(asio::buffer(-          asio::buffer(vector_, max_size_) + pos, n));-  }--  /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the-  /// underlying memory.-  /**-   * @param pos Position of the first byte to represent in the buffer sequence-   *-   * @param n The number of bytes to return in the buffer sequence. If the-   * underlying memory is shorter, the buffer sequence represents as many bytes-   * as are available.-   *-   * @note The returned object is invalidated by any @c dynamic_vector_buffer-   * or @c vector member function that resizes or erases the vector.-   */-  const_buffers_type data(std::size_t pos,-      std::size_t n) const noexcept-  {-    return const_buffers_type(asio::buffer(-          asio::buffer(vector_, max_size_) + pos, n));-  }--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  /// @b DynamicBuffer_v1: Get a list of buffers that represents the output-  /// sequence, with the given size.-  /**-   * Ensures that the output sequence can accommodate @c n bytes, resizing the-   * vector object as necessary.-   *-   * @returns An object of type @c mutable_buffers_type that satisfies-   * MutableBufferSequence requirements, representing vector memory at the-   * start of the output sequence of size @c n.-   *-   * @throws std::length_error If <tt>size() + n > max_size()</tt>.-   *-   * @note The returned object is invalidated by any @c dynamic_vector_buffer-   * or @c vector member function that modifies the input sequence or output-   * sequence.-   */-  mutable_buffers_type prepare(std::size_t n)-  {-    if (size () > max_size() || max_size() - size() < n)-    {-      std::length_error ex("dynamic_vector_buffer too long");-      asio::detail::throw_exception(ex);-    }--    if (size_ == (std::numeric_limits<std::size_t>::max)())-      size_ = vector_.size(); // Enable v1 behaviour.--    vector_.resize(size_ + n);--    return asio::buffer(asio::buffer(vector_) + size_, n);-  }--  /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input-  /// sequence.-  /**-   * @param n The number of bytes to append from the start of the output-   * sequence to the end of the input sequence. The remainder of the output-   * sequence is discarded.-   *-   * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and-   * no intervening operations that modify the input or output sequence.-   *-   * @note If @c n is greater than the size of the output sequence, the entire-   * output sequence is moved to the input sequence and no error is issued.-   */-  void commit(std::size_t n)-  {-    size_ += (std::min)(n, vector_.size() - size_);-    vector_.resize(size_);-  }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--  /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of-  /// bytes.-  /**-   * Resizes the vector to accommodate an additional @c n bytes at the end.-   *-   * @throws std::length_error If <tt>size() + n > max_size()</tt>.-   */-  void grow(std::size_t n)-  {-    if (size() > max_size() || max_size() - size() < n)-    {-      std::length_error ex("dynamic_vector_buffer too long");-      asio::detail::throw_exception(ex);-    }--    vector_.resize(size() + n);-  }--  /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number-  /// of bytes.-  /**-   * Erases @c n bytes from the end of the vector by resizing the vector-   * object. If @c n is greater than the current size of the vector, the vector-   * is emptied.-   */-  void shrink(std::size_t n)-  {-    vector_.resize(n > size() ? 0 : size() - n);-  }--  /// @b DynamicBuffer_v1: Remove characters from the input sequence.-  /// @b DynamicBuffer_v2: Consume the specified number of bytes from the-  /// beginning of the underlying memory.-  /**-   * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the-   * input sequence. @note If @c n is greater than the size of the input-   * sequence, the entire input sequence is consumed and no error is issued.-   *-   * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the vector.-   * If @c n is greater than the current size of the vector, the vector is-   * emptied.-   */-  void consume(std::size_t n)-  {-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-    if (size_ != (std::numeric_limits<std::size_t>::max)())-    {-      std::size_t consume_length = (std::min)(n, size_);-      vector_.erase(vector_.begin(), vector_.begin() + consume_length);-      size_ -= consume_length;-      return;-    }-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-    vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n));-  }--private:-  std::vector<Elem, Allocator>& vector_;-#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  std::size_t size_;-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  const std::size_t max_size_;-};--/** @defgroup dynamic_buffer asio::dynamic_buffer- *- * @brief The asio::dynamic_buffer function is used to create a- * dynamically resized buffer from a @c std::basic_string or @c std::vector.- */-/*@{*/--/// Create a new dynamic buffer that represents the given string.-/**- * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data)</tt>.- */-template <typename Elem, typename Traits, typename Allocator>-ASIO_NODISCARD inline-dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(-    std::basic_string<Elem, Traits, Allocator>& data) noexcept-{-  return dynamic_string_buffer<Elem, Traits, Allocator>(data);-}--/// Create a new dynamic buffer that represents the given string.-/**- * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data,- * max_size)</tt>.- */-template <typename Elem, typename Traits, typename Allocator>-ASIO_NODISCARD inline-dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(-    std::basic_string<Elem, Traits, Allocator>& data,-    std::size_t max_size) noexcept-{-  return dynamic_string_buffer<Elem, Traits, Allocator>(data, max_size);-}--/// Create a new dynamic buffer that represents the given vector.-/**- * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data)</tt>.- */-template <typename Elem, typename Allocator>-ASIO_NODISCARD inline-dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(-    std::vector<Elem, Allocator>& data) noexcept-{-  return dynamic_vector_buffer<Elem, Allocator>(data);-}--/// Create a new dynamic buffer that represents the given vector.-/**- * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data, max_size)</tt>.- */-template <typename Elem, typename Allocator>-ASIO_NODISCARD inline-dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(-    std::vector<Elem, Allocator>& data,-    std::size_t max_size) noexcept-{-  return dynamic_vector_buffer<Elem, Allocator>(data, max_size);-}--/*@}*/--/** @defgroup buffer_copy asio::buffer_copy- *- * @brief The asio::buffer_copy function is used to copy bytes from a- * source buffer (or buffer sequence) to a target buffer (or buffer sequence).- *- * The @c buffer_copy function is available in two forms:- *- * @li A 2-argument form: @c buffer_copy(target, source)- *- * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy)- *- * Both forms return the number of bytes actually copied. The number of bytes- * copied is the lesser of:- *- * @li @c buffer_size(target)- *- * @li @c buffer_size(source)- *- * @li @c If specified, @c max_bytes_to_copy.- *- * This prevents buffer overflow, regardless of the buffer sizes used in the- * copy operation.- *- * Note that @ref buffer_copy is implemented in terms of @c memcpy, and- * consequently it cannot be used to copy between overlapping memory regions.- */-/*@{*/--namespace detail {--inline std::size_t buffer_copy_1(const mutable_buffer& target,-    const const_buffer& source)-{-  using namespace std; // For memcpy.-  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;-  if (n > 0)-    memcpy(target.data(), source.data(), n);-  return n;-}--template <typename TargetIterator, typename SourceIterator>-inline std::size_t buffer_copy(one_buffer, one_buffer,-    TargetIterator target_begin, TargetIterator,-    SourceIterator source_begin, SourceIterator) noexcept-{-  return (buffer_copy_1)(*target_begin, *source_begin);-}--template <typename TargetIterator, typename SourceIterator>-inline std::size_t buffer_copy(one_buffer, one_buffer,-    TargetIterator target_begin, TargetIterator,-    SourceIterator source_begin, SourceIterator,-    std::size_t max_bytes_to_copy) noexcept-{-  return (buffer_copy_1)(*target_begin,-      asio::buffer(*source_begin, max_bytes_to_copy));-}--template <typename TargetIterator, typename SourceIterator>-std::size_t buffer_copy(one_buffer, multiple_buffers,-    TargetIterator target_begin, TargetIterator,-    SourceIterator source_begin, SourceIterator source_end,-    std::size_t max_bytes_to_copy-      = (std::numeric_limits<std::size_t>::max)()) noexcept-{-  std::size_t total_bytes_copied = 0;-  SourceIterator source_iter = source_begin;--  for (mutable_buffer target_buffer(-        asio::buffer(*target_begin, max_bytes_to_copy));-      target_buffer.size() && source_iter != source_end; ++source_iter)-  {-    const_buffer source_buffer(*source_iter);-    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);-    total_bytes_copied += bytes_copied;-    target_buffer += bytes_copied;-  }--  return total_bytes_copied;-}--template <typename TargetIterator, typename SourceIterator>-std::size_t buffer_copy(multiple_buffers, one_buffer,-    TargetIterator target_begin, TargetIterator target_end,-    SourceIterator source_begin, SourceIterator,-    std::size_t max_bytes_to_copy-      = (std::numeric_limits<std::size_t>::max)()) noexcept-{-  std::size_t total_bytes_copied = 0;-  TargetIterator target_iter = target_begin;--  for (const_buffer source_buffer(-        asio::buffer(*source_begin, max_bytes_to_copy));-      source_buffer.size() && target_iter != target_end; ++target_iter)-  {-    mutable_buffer target_buffer(*target_iter);-    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);-    total_bytes_copied += bytes_copied;-    source_buffer += bytes_copied;-  }--  return total_bytes_copied;-}--template <typename TargetIterator, typename SourceIterator>-std::size_t buffer_copy(multiple_buffers, multiple_buffers,-    TargetIterator target_begin, TargetIterator target_end,-    SourceIterator source_begin, SourceIterator source_end) noexcept-{-  std::size_t total_bytes_copied = 0;--  TargetIterator target_iter = target_begin;-  std::size_t target_buffer_offset = 0;--  SourceIterator source_iter = source_begin;-  std::size_t source_buffer_offset = 0;--  while (target_iter != target_end && source_iter != source_end)-  {-    mutable_buffer target_buffer =-      mutable_buffer(*target_iter) + target_buffer_offset;--    const_buffer source_buffer =-      const_buffer(*source_iter) + source_buffer_offset;--    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);-    total_bytes_copied += bytes_copied;--    if (bytes_copied == target_buffer.size())-    {-      ++target_iter;-      target_buffer_offset = 0;-    }-    else-      target_buffer_offset += bytes_copied;--    if (bytes_copied == source_buffer.size())-    {-      ++source_iter;-      source_buffer_offset = 0;-    }-    else-      source_buffer_offset += bytes_copied;-  }--  return total_bytes_copied;-}--template <typename TargetIterator, typename SourceIterator>-std::size_t buffer_copy(multiple_buffers, multiple_buffers,-    TargetIterator target_begin, TargetIterator target_end,-    SourceIterator source_begin, SourceIterator source_end,-    std::size_t max_bytes_to_copy) noexcept-{-  std::size_t total_bytes_copied = 0;--  TargetIterator target_iter = target_begin;-  std::size_t target_buffer_offset = 0;--  SourceIterator source_iter = source_begin;-  std::size_t source_buffer_offset = 0;--  while (total_bytes_copied != max_bytes_to_copy-      && target_iter != target_end && source_iter != source_end)-  {-    mutable_buffer target_buffer =-      mutable_buffer(*target_iter) + target_buffer_offset;--    const_buffer source_buffer =-      const_buffer(*source_iter) + source_buffer_offset;--    std::size_t bytes_copied = (buffer_copy_1)(-        target_buffer, asio::buffer(source_buffer,-          max_bytes_to_copy - total_bytes_copied));-    total_bytes_copied += bytes_copied;--    if (bytes_copied == target_buffer.size())-    {-      ++target_iter;-      target_buffer_offset = 0;-    }-    else-      target_buffer_offset += bytes_copied;--    if (bytes_copied == source_buffer.size())-    {-      ++source_iter;-      source_buffer_offset = 0;-    }-    else-      source_buffer_offset += bytes_copied;-  }--  return total_bytes_copied;-}--} // namespace detail--/// Copies bytes from a source buffer sequence to a target buffer sequence.-/**- * @param target A modifiable buffer sequence representing the memory regions to- * which the bytes will be copied.- *- * @param source A non-modifiable buffer sequence representing the memory- * regions from which the bytes will be copied.- *- * @returns The number of bytes copied.- *- * @note The number of bytes copied is the lesser of:- *- * @li @c buffer_size(target)- *- * @li @c buffer_size(source)- *- * This function is implemented in terms of @c memcpy, and consequently it- * cannot be used to copy between overlapping memory regions.- */-template <typename MutableBufferSequence, typename ConstBufferSequence>-inline std::size_t buffer_copy(const MutableBufferSequence& target,-    const ConstBufferSequence& source) noexcept-{-  return detail::buffer_copy(-      detail::buffer_sequence_cardinality<MutableBufferSequence>(),-      detail::buffer_sequence_cardinality<ConstBufferSequence>(),-      asio::buffer_sequence_begin(target),-      asio::buffer_sequence_end(target),-      asio::buffer_sequence_begin(source),-      asio::buffer_sequence_end(source));-}--/// Copies a limited number of bytes from a source buffer sequence to a target-/// buffer sequence.-/**- * @param target A modifiable buffer sequence representing the memory regions to- * which the bytes will be copied.- *- * @param source A non-modifiable buffer sequence representing the memory- * regions from which the bytes will be copied.- *- * @param max_bytes_to_copy The maximum number of bytes to be copied.- *- * @returns The number of bytes copied.- *- * @note The number of bytes copied is the lesser of:- *- * @li @c buffer_size(target)- *- * @li @c buffer_size(source)- *- * @li @c max_bytes_to_copy- *- * This function is implemented in terms of @c memcpy, and consequently it- * cannot be used to copy between overlapping memory regions.- */-template <typename MutableBufferSequence, typename ConstBufferSequence>-inline std::size_t buffer_copy(const MutableBufferSequence& target,-    const ConstBufferSequence& source,-    std::size_t max_bytes_to_copy) noexcept-{-  return detail::buffer_copy(-      detail::buffer_sequence_cardinality<MutableBufferSequence>(),-      detail::buffer_sequence_cardinality<ConstBufferSequence>(),-      asio::buffer_sequence_begin(target),-      asio::buffer_sequence_end(target),-      asio::buffer_sequence_begin(source),-      asio::buffer_sequence_end(source), max_bytes_to_copy);-}--/*@}*/--} // namespace asio--#include "asio/detail/pop_options.hpp"-#include "asio/detail/is_buffer_sequence.hpp"-#include "asio/detail/push_options.hpp"--namespace asio {--/// Trait to determine whether a type satisfies the MutableBufferSequence-/// requirements.-template <typename T>-struct is_mutable_buffer_sequence-#if defined(GENERATING_DOCUMENTATION)-  : integral_constant<bool, automatically_determined>-#else // defined(GENERATING_DOCUMENTATION)-  : asio::detail::is_buffer_sequence<T, mutable_buffer>-#endif // defined(GENERATING_DOCUMENTATION)-{-};--/// Trait to determine whether a type satisfies the ConstBufferSequence-/// requirements.-template <typename T>-struct is_const_buffer_sequence-#if defined(GENERATING_DOCUMENTATION)-  : integral_constant<bool, automatically_determined>-#else // defined(GENERATING_DOCUMENTATION)-  : asio::detail::is_buffer_sequence<T, const_buffer>-#endif // defined(GENERATING_DOCUMENTATION)-{-};--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)-/// Trait to determine whether a type satisfies the DynamicBuffer_v1-/// requirements.-template <typename T>-struct is_dynamic_buffer_v1-#if defined(GENERATING_DOCUMENTATION)-  : integral_constant<bool, automatically_determined>-#else // defined(GENERATING_DOCUMENTATION)-  : asio::detail::is_dynamic_buffer_v1<T>-#endif // defined(GENERATING_DOCUMENTATION)-{-};-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--/// Trait to determine whether a type satisfies the DynamicBuffer_v2-/// requirements.-template <typename T>-struct is_dynamic_buffer_v2-#if defined(GENERATING_DOCUMENTATION)-  : integral_constant<bool, automatically_determined>-#else // defined(GENERATING_DOCUMENTATION)-  : asio::detail::is_dynamic_buffer_v2<T>-#endif // defined(GENERATING_DOCUMENTATION)-{-};--/// Trait to determine whether a type satisfies the DynamicBuffer requirements.-/**- * If @c ASIO_NO_DYNAMIC_BUFFER_V1 is not defined, determines whether the- * type satisfies the DynamicBuffer_v1 requirements. Otherwise, if @c- * ASIO_NO_DYNAMIC_BUFFER_V1 is defined, determines whether the type- * satisfies the DynamicBuffer_v2 requirements.- */-template <typename T>-struct is_dynamic_buffer-#if defined(GENERATING_DOCUMENTATION)-  : integral_constant<bool, automatically_determined>-#elif defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  : asio::is_dynamic_buffer_v2<T>-#else // defined(ASIO_NO_DYNAMIC_BUFFER_V1)-  : asio::is_dynamic_buffer_v1<T>-#endif // defined(ASIO_NO_DYNAMIC_BUFFER_V1)-{-};--namespace buffer_literals {-namespace detail {--template <char... Chars>-struct chars {};--template <unsigned char... Bytes>-struct bytes {};--// Literal processor that converts binary literals to an array of bytes.--template <typename Bytes, char... Chars>-struct bin_literal;--template <unsigned char... Bytes>-struct bin_literal<bytes<Bytes...>>-{-  static const std::size_t size = sizeof...(Bytes);-  static const unsigned char data[sizeof...(Bytes)];-};--template <unsigned char... Bytes>-const unsigned char bin_literal<bytes<Bytes...>>::data[sizeof...(Bytes)]-  = { Bytes... };--template <unsigned char... Bytes, char Bit7, char Bit6, char Bit5,-    char Bit4, char Bit3, char Bit2, char Bit1, char Bit0, char... Chars>-struct bin_literal<bytes<Bytes...>, Bit7, Bit6,-    Bit5, Bit4, Bit3, Bit2, Bit1, Bit0, Chars...> :-  bin_literal<-    bytes<Bytes...,-      static_cast<unsigned char>(-      (Bit7 == '1' ? 0x80 : 0) |-        (Bit6 == '1' ? 0x40 : 0) |-        (Bit5 == '1' ? 0x20 : 0) |-        (Bit4 == '1' ? 0x10 : 0) |-        (Bit3 == '1' ? 0x08 : 0) |-        (Bit2 == '1' ? 0x04 : 0) |-        (Bit1 == '1' ? 0x02 : 0) |-        (Bit0 == '1' ? 0x01 : 0))-    >, Chars...> {};--template <unsigned char... Bytes, char... Chars>-struct bin_literal<bytes<Bytes...>, Chars...>-{-  static_assert(sizeof...(Chars) == 0,-      "number of digits in a binary buffer literal must be a multiple of 8");--  static const std::size_t size = 0;-  static const unsigned char data[1];-};--template <unsigned char... Bytes, char... Chars>-const unsigned char bin_literal<bytes<Bytes...>, Chars...>::data[1] = {};--// Literal processor that converts hexadecimal literals to an array of bytes.--template <typename Bytes, char... Chars>-struct hex_literal;--template <unsigned char... Bytes>-struct hex_literal<bytes<Bytes...>>-{-  static const std::size_t size = sizeof...(Bytes);-  static const unsigned char data[sizeof...(Bytes)];-};--template <unsigned char... Bytes>-const unsigned char hex_literal<bytes<Bytes...>>::data[sizeof...(Bytes)]-  = { Bytes... };--template <unsigned char... Bytes, char Hi, char Lo, char... Chars>-struct hex_literal<bytes<Bytes...>, Hi, Lo, Chars...> :-  hex_literal<-    bytes<Bytes...,-      static_cast<unsigned char>(-        Lo >= 'A' && Lo <= 'F' ? Lo - 'A' + 10 :-          (Lo >= 'a' && Lo <= 'f' ? Lo - 'a' + 10 : Lo - '0')) |-      ((static_cast<unsigned char>(-        Hi >= 'A' && Hi <= 'F' ? Hi - 'A' + 10 :-          (Hi >= 'a' && Hi <= 'f' ? Hi - 'a' + 10 : Hi - '0'))) << 4)-    >, Chars...> {};--template <unsigned char... Bytes, char Char>-struct hex_literal<bytes<Bytes...>, Char>-{-  static_assert(!Char,-      "a hexadecimal buffer literal must have an even number of digits");--  static const std::size_t size = 0;-  static const unsigned char data[1];-};--template <unsigned char... Bytes, char Char>-const unsigned char hex_literal<bytes<Bytes...>, Char>::data[1] = {};--// Helper template that removes digit separators and then passes the cleaned-// variadic pack of characters to the literal processor.--template <template <typename, char...> class Literal,-    typename Clean, char... Raw>-struct remove_separators;--template <template <typename, char...> class Literal,-    char... Clean, char... Raw>-struct remove_separators<Literal, chars<Clean...>, '\'', Raw...> :-  remove_separators<Literal, chars<Clean...>, Raw...> {};--template <template <typename, char...> class Literal,-    char... Clean, char C, char... Raw>-struct remove_separators<Literal, chars<Clean...>, C, Raw...> :-  remove_separators<Literal, chars<Clean..., C>, Raw...> {};--template <template <typename, char...> class Literal, char... Clean>-struct remove_separators<Literal, chars<Clean...>> :-  Literal<bytes<>, Clean...> {};--// Helper template to determine the literal type based on the prefix.--template <char... Chars>-struct literal;--template <char... Chars>-struct literal<'0', 'b', Chars...> :-  remove_separators<bin_literal, chars<>, Chars...>{};--template <char... Chars>-struct literal<'0', 'B', Chars...> :-  remove_separators<bin_literal, chars<>, Chars...>{};--template <char... Chars>-struct literal<'0', 'x', Chars...> :-  remove_separators<hex_literal, chars<>, Chars...>{};--template <char... Chars>-struct literal<'0', 'X', Chars...> :-  remove_separators<hex_literal, chars<>, Chars...>{};--} // namespace detail--/// Literal operator for creating const_buffer objects from string literals.-inline const_buffer operator ""_buf(const char* data, std::size_t n)-{-  return const_buffer(data, n);-}--/// Literal operator for creating const_buffer objects from unbounded binary or-/// hexadecimal integer literals.-template <char... Chars>-inline const_buffer operator ""_buf()-{-  return const_buffer(-      +detail::literal<Chars...>::data,-      detail::literal<Chars...>::size);-}--} // namespace buffer_literals+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_BUFFER_HPP+#define ASIO_BUFFER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <cstddef>+#include <cstring>+#include <limits>+#include <stdexcept>+#include <string>+#include <vector>+#include "asio/detail/array_fwd.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/string_view.hpp"+#include "asio/detail/throw_exception.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/is_contiguous_iterator.hpp"++#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1700)+# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)+#  if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)+#   define ASIO_ENABLE_BUFFER_DEBUGGING+#  endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)+# endif // defined(_HAS_ITERATOR_DEBUGGING)+#endif // defined(ASIO_MSVC) && (ASIO_MSVC >= 1700)++#if defined(__GNUC__)+# if defined(_GLIBCXX_DEBUG)+#  if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)+#   define ASIO_ENABLE_BUFFER_DEBUGGING+#  endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)+# endif // defined(_GLIBCXX_DEBUG)+#endif // defined(__GNUC__)++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+# include "asio/detail/functional.hpp"+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++#if defined(ASIO_HAS_BOOST_WORKAROUND)+# include <boost/detail/workaround.hpp>+# if !defined(__clang__)+#  if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))+#   define ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND+#  endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))+# elif BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))+#  define ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND+# endif // BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))+#endif // defined(ASIO_HAS_BOOST_WORKAROUND)++#if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)+# include "asio/detail/type_traits.hpp"+#endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)++#include "asio/detail/push_options.hpp"++namespace asio {++class mutable_buffer;+class const_buffer;++/// Holds a buffer that can be modified.+/**+ * The mutable_buffer class provides a safe representation of a buffer that can+ * be modified. It does not own the underlying data, and so is cheap to copy or+ * assign.+ *+ * @par Accessing Buffer Contents+ *+ * 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 = b1.size();+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());+ * @endcode+ *+ * The @c data() member function permits violations of type safety, so uses of+ * it in application code should be carefully considered.+ */+class mutable_buffer+{+public:+  /// Construct an empty buffer.+  mutable_buffer() ASIO_NOEXCEPT+    : data_(0),+      size_(0)+  {+  }++  /// Construct a buffer to represent a given memory range.+  mutable_buffer(void* data, std::size_t size) ASIO_NOEXCEPT+    : data_(data),+      size_(size)+  {+  }++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+  mutable_buffer(void* data, std::size_t size,+      asio::detail::function<void()> debug_check)+    : data_(data),+      size_(size),+      debug_check_(debug_check)+  {+  }++  const asio::detail::function<void()>& get_debug_check() const+  {+    return debug_check_;+  }+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++  /// Get a pointer to the beginning of the memory range.+  void* data() const ASIO_NOEXCEPT+  {+#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 ASIO_NOEXCEPT+  {+    return size_;+  }++  /// Move the start of the buffer by the specified number of bytes.+  mutable_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT+  {+    std::size_t offset = n < size_ ? n : size_;+    data_ = static_cast<char*>(data_) + offset;+    size_ -= offset;+    return *this;+  }++private:+  void* data_;+  std::size_t size_;++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+  asio::detail::function<void()> debug_check_;+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+};++#if !defined(ASIO_NO_DEPRECATED)++/// (Deprecated: Use mutable_buffer.) Adapts a single modifiable buffer so that+/// it meets the requirements of the MutableBufferSequence concept.+class mutable_buffers_1+  : public mutable_buffer+{+public:+  /// The type for each element in the list of buffers.+  typedef mutable_buffer value_type;++  /// A random-access iterator type that may be used to read elements.+  typedef const mutable_buffer* const_iterator;++  /// Construct to represent a given memory range.+  mutable_buffers_1(void* data, std::size_t size) ASIO_NOEXCEPT+    : mutable_buffer(data, size)+  {+  }++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+  mutable_buffers_1(void* data, std::size_t size,+      asio::detail::function<void()> debug_check)+    : mutable_buffer(data, size, debug_check)+  {+  }+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++  /// Construct to represent a single modifiable buffer.+  explicit mutable_buffers_1(const mutable_buffer& b) ASIO_NOEXCEPT+    : mutable_buffer(b)+  {+  }++  /// Get a random-access iterator to the first element.+  const_iterator begin() const ASIO_NOEXCEPT+  {+    return this;+  }++  /// Get a random-access iterator for one past the last element.+  const_iterator end() const ASIO_NOEXCEPT+  {+    return begin() + 1;+  }+};++#endif // !defined(ASIO_NO_DEPRECATED)++/// Holds a buffer that cannot be modified.+/**+ * The const_buffer class provides a safe representation of a buffer that cannot+ * be modified. It does not own the underlying data, and so is cheap to copy or+ * assign.+ *+ * @par Accessing Buffer Contents+ *+ * 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 = b1.size();+ * const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());+ * @endcode+ *+ * The @c data() member function permits violations of type safety, so uses of+ * it in application code should be carefully considered.+ */+class const_buffer+{+public:+  /// Construct an empty buffer.+  const_buffer() ASIO_NOEXCEPT+    : data_(0),+      size_(0)+  {+  }++  /// Construct a buffer to represent a given memory range.+  const_buffer(const void* data, std::size_t size) ASIO_NOEXCEPT+    : data_(data),+      size_(size)+  {+  }++  /// Construct a non-modifiable buffer from a modifiable one.+  const_buffer(const mutable_buffer& b) ASIO_NOEXCEPT+    : data_(b.data()),+      size_(b.size())+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , debug_check_(b.get_debug_check())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+  {+  }++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+  const_buffer(const void* data, std::size_t size,+      asio::detail::function<void()> debug_check)+    : data_(data),+      size_(size),+      debug_check_(debug_check)+  {+  }++  const asio::detail::function<void()>& get_debug_check() const+  {+    return debug_check_;+  }+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++  /// Get a pointer to the beginning of the memory range.+  const void* data() const ASIO_NOEXCEPT+  {+#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 ASIO_NOEXCEPT+  {+    return size_;+  }++  /// Move the start of the buffer by the specified number of bytes.+  const_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT+  {+    std::size_t offset = n < size_ ? n : size_;+    data_ = static_cast<const char*>(data_) + offset;+    size_ -= offset;+    return *this;+  }++private:+  const void* data_;+  std::size_t size_;++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+  asio::detail::function<void()> debug_check_;+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+};++#if !defined(ASIO_NO_DEPRECATED)++/// (Deprecated: Use const_buffer.) Adapts a single non-modifiable buffer so+/// that it meets the requirements of the ConstBufferSequence concept.+class const_buffers_1+  : public const_buffer+{+public:+  /// The type for each element in the list of buffers.+  typedef const_buffer value_type;++  /// A random-access iterator type that may be used to read elements.+  typedef const const_buffer* const_iterator;++  /// Construct to represent a given memory range.+  const_buffers_1(const void* data, std::size_t size) ASIO_NOEXCEPT+    : const_buffer(data, size)+  {+  }++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+  const_buffers_1(const void* data, std::size_t size,+      asio::detail::function<void()> debug_check)+    : const_buffer(data, size, debug_check)+  {+  }+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++  /// Construct to represent a single non-modifiable buffer.+  explicit const_buffers_1(const const_buffer& b) ASIO_NOEXCEPT+    : const_buffer(b)+  {+  }++  /// Get a random-access iterator to the first element.+  const_iterator begin() const ASIO_NOEXCEPT+  {+    return this;+  }++  /// Get a random-access iterator for one past the last element.+  const_iterator end() const ASIO_NOEXCEPT+  {+    return begin() + 1;+  }+};++#endif // !defined(ASIO_NO_DEPRECATED)++/// (Deprecated: Use the socket/descriptor wait() and async_wait() member+/// functions.) An implementation of both the ConstBufferSequence and+/// MutableBufferSequence concepts to represent a null buffer sequence.+class null_buffers+{+public:+  /// The type for each element in the list of buffers.+  typedef mutable_buffer value_type;++  /// A random-access iterator type that may be used to read elements.+  typedef const mutable_buffer* const_iterator;++  /// Get a random-access iterator to the first element.+  const_iterator begin() const ASIO_NOEXCEPT+  {+    return &buf_;+  }++  /// Get a random-access iterator for one past the last element.+  const_iterator end() const ASIO_NOEXCEPT+  {+    return &buf_;+  }++private:+  mutable_buffer buf_;+};++/** @defgroup buffer_sequence_begin asio::buffer_sequence_begin+ *+ * @brief The asio::buffer_sequence_begin function returns an iterator+ * pointing to the first element in a buffer sequence.+ */+/*@{*/++/// Get an iterator to the first element in a buffer sequence.+template <typename MutableBuffer>+inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,+    typename constraint<+      is_convertible<const MutableBuffer*, const mutable_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT+{+  return static_cast<const mutable_buffer*>(detail::addressof(b));+}++/// Get an iterator to the first element in a buffer sequence.+template <typename ConstBuffer>+inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,+    typename constraint<+      is_convertible<const ConstBuffer*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT+{+  return static_cast<const const_buffer*>(detail::addressof(b));+}++#if defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)++/// Get an iterator to the first element in a buffer sequence.+template <typename C>+inline auto buffer_sequence_begin(C& c,+    typename constraint<+      !is_convertible<const C*, const mutable_buffer*>::value+        && !is_convertible<const C*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT -> decltype(c.begin())+{+  return c.begin();+}++/// Get an iterator to the first element in a buffer sequence.+template <typename C>+inline auto buffer_sequence_begin(const C& c,+    typename constraint<+      !is_convertible<const C*, const mutable_buffer*>::value+        && !is_convertible<const C*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT -> decltype(c.begin())+{+  return c.begin();+}++#else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)++template <typename C>+inline typename C::iterator buffer_sequence_begin(C& c,+    typename constraint<+      !is_convertible<const C*, const mutable_buffer*>::value+        && !is_convertible<const C*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT+{+  return c.begin();+}++template <typename C>+inline typename C::const_iterator buffer_sequence_begin(const C& c,+    typename constraint<+      !is_convertible<const C*, const mutable_buffer*>::value+        && !is_convertible<const C*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT+{+  return c.begin();+}++#endif // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)++/*@}*/++/** @defgroup buffer_sequence_end asio::buffer_sequence_end+ *+ * @brief The asio::buffer_sequence_end function returns an iterator+ * pointing to one past the end element in a buffer sequence.+ */+/*@{*/++/// Get an iterator to one past the end element in a buffer sequence.+template <typename MutableBuffer>+inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,+    typename constraint<+      is_convertible<const MutableBuffer*, const mutable_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT+{+  return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;+}++/// Get an iterator to one past the end element in a buffer sequence.+template <typename ConstBuffer>+inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,+    typename constraint<+      is_convertible<const ConstBuffer*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT+{+  return static_cast<const const_buffer*>(detail::addressof(b)) + 1;+}++#if defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)++/// Get an iterator to one past the end element in a buffer sequence.+template <typename C>+inline auto buffer_sequence_end(C& c,+    typename constraint<+      !is_convertible<const C*, const mutable_buffer*>::value+        && !is_convertible<const C*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT -> decltype(c.end())+{+  return c.end();+}++/// Get an iterator to one past the end element in a buffer sequence.+template <typename C>+inline auto buffer_sequence_end(const C& c,+    typename constraint<+      !is_convertible<const C*, const mutable_buffer*>::value+        && !is_convertible<const C*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT -> decltype(c.end())+{+  return c.end();+}++#else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)++template <typename C>+inline typename C::iterator buffer_sequence_end(C& c,+    typename constraint<+      !is_convertible<const C*, const mutable_buffer*>::value+        && !is_convertible<const C*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT+{+  return c.end();+}++template <typename C>+inline typename C::const_iterator buffer_sequence_end(const C& c,+    typename constraint<+      !is_convertible<const C*, const mutable_buffer*>::value+        && !is_convertible<const C*, const const_buffer*>::value+    >::type = 0) ASIO_NOEXCEPT+{+  return c.end();+}++#endif // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)++/*@}*/++namespace detail {++// Tag types used to select appropriately optimised overloads.+struct one_buffer {};+struct multiple_buffers {};++// Helper trait to detect single buffers.+template <typename BufferSequence>+struct buffer_sequence_cardinality :+  conditional<+    is_same<BufferSequence, mutable_buffer>::value+#if !defined(ASIO_NO_DEPRECATED)+      || is_same<BufferSequence, mutable_buffers_1>::value+      || is_same<BufferSequence, const_buffers_1>::value+#endif // !defined(ASIO_NO_DEPRECATED)+      || is_same<BufferSequence, const_buffer>::value,+    one_buffer, multiple_buffers>::type {};++template <typename Iterator>+inline std::size_t buffer_size(one_buffer,+    Iterator begin, Iterator) ASIO_NOEXCEPT+{+  return const_buffer(*begin).size();+}++template <typename Iterator>+inline std::size_t buffer_size(multiple_buffers,+    Iterator begin, Iterator end) ASIO_NOEXCEPT+{+  std::size_t total_buffer_size = 0;++  Iterator iter = begin;+  for (; iter != end; ++iter)+  {+    const_buffer b(*iter);+    total_buffer_size += b.size();+  }++  return total_buffer_size;+}++} // namespace detail++/// Get the total number of bytes in a buffer sequence.+/**+ * The @c buffer_size function determines the total size of all buffers in the+ * buffer sequence, as if computed as follows:+ *+ * @code size_t total_size = 0;+ * auto i = asio::buffer_sequence_begin(buffers);+ * auto end = asio::buffer_sequence_end(buffers);+ * for (; i != end; ++i)+ * {+ *   const_buffer b(*i);+ *   total_size += b.size();+ * }+ * return total_size; @endcode+ *+ * The @c BufferSequence template parameter may meet either of the @c+ * ConstBufferSequence or @c MutableBufferSequence type requirements.+ */+template <typename BufferSequence>+inline std::size_t buffer_size(const BufferSequence& b) ASIO_NOEXCEPT+{+  return detail::buffer_size(+      detail::buffer_sequence_cardinality<BufferSequence>(),+      asio::buffer_sequence_begin(b),+      asio::buffer_sequence_end(b));+}++#if !defined(ASIO_NO_DEPRECATED)++/** @defgroup buffer_cast asio::buffer_cast+ *+ * @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:+ *+ * To access the memory of a non-modifiable buffer, use:+ * @code asio::const_buffer b1 = ...;+ * const unsigned char* p1 = asio::buffer_cast<const unsigned char*>(b1);+ * @endcode+ *+ * To access the memory of a modifiable buffer, use:+ * @code asio::mutable_buffer b2 = ...;+ * unsigned char* p2 = asio::buffer_cast<unsigned char*>(b2);+ * @endcode+ *+ * The asio::buffer_cast function permits violations of type safety, so+ * uses of it in application code should be carefully considered.+ */+/*@{*/++/// Cast a non-modifiable buffer to a specified pointer to POD type.+template <typename PointerToPodType>+inline PointerToPodType buffer_cast(const mutable_buffer& b) ASIO_NOEXCEPT+{+  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) ASIO_NOEXCEPT+{+  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 n) ASIO_NOEXCEPT+{+  std::size_t offset = n < b.size() ? n : b.size();+  char* new_data = static_cast<char*>(b.data()) + offset;+  std::size_t new_size = b.size() - offset;+  return mutable_buffer(new_data, new_size+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , b.get_debug_check()+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new modifiable buffer that is offset from the start of another.+/**+ * @relates mutable_buffer+ */+inline mutable_buffer operator+(std::size_t n,+    const mutable_buffer& b) ASIO_NOEXCEPT+{+  return b + n;+}++/// Create a new non-modifiable buffer that is offset from the start of another.+/**+ * @relates const_buffer+ */+inline const_buffer operator+(const const_buffer& b,+    std::size_t n) ASIO_NOEXCEPT+{+  std::size_t offset = n < b.size() ? n : b.size();+  const char* new_data = static_cast<const char*>(b.data()) + offset;+  std::size_t new_size = b.size() - offset;+  return const_buffer(new_data, new_size+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , b.get_debug_check()+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new non-modifiable buffer that is offset from the start of another.+/**+ * @relates const_buffer+ */+inline const_buffer operator+(std::size_t n,+    const const_buffer& b) ASIO_NOEXCEPT+{+  return b + n;+}++#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+namespace detail {++template <typename Iterator>+class buffer_debug_check+{+public:+  buffer_debug_check(Iterator iter)+    : iter_(iter)+  {+  }++  ~buffer_debug_check()+  {+#if defined(ASIO_MSVC) && (ASIO_MSVC == 1400)+    // MSVC 8's string iterator checking may crash in a std::string::iterator+    // object's destructor when the iterator points to an already-destroyed+    // std::string object, unless the iterator is cleared first.+    iter_ = Iterator();+#endif // defined(ASIO_MSVC) && (ASIO_MSVC == 1400)+  }++  void operator()()+  {+    (void)*iter_;+  }++private:+  Iterator iter_;+};++} // namespace detail+#endif // ASIO_ENABLE_BUFFER_DEBUGGING++/** @defgroup buffer asio::buffer+ *+ * @brief The asio::buffer function is used to create a buffer object to+ * represent raw memory, an array of POD elements, a vector of POD elements,+ * or a std::string.+ *+ * A buffer object represents a contiguous region of memory as a 2-tuple+ * consisting of a pointer and size in bytes. A tuple of the form <tt>{void*,+ * size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a+ * tuple of the form <tt>{const void*, size_t}</tt> specifies a const+ * (non-modifiable) region of memory. These two forms correspond to the classes+ * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion+ * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the+ * opposite conversion is not permitted.+ *+ * The simplest use case involves reading or writing a single buffer of a+ * specified size:+ *+ * @code sock.send(asio::buffer(data, size)); @endcode+ *+ * In the above example, the return value of asio::buffer meets the+ * requirements of the ConstBufferSequence concept so that it may be directly+ * passed to the socket's write function. A buffer created for modifiable+ * memory also meets the requirements of the MutableBufferSequence concept.+ *+ * An individual buffer may be created from a builtin array, std::vector,+ * std::array or boost::array of POD elements. This helps prevent buffer+ * overruns by automatically determining the size of the buffer:+ *+ * @code char d1[128];+ * size_t bytes_transferred = sock.receive(asio::buffer(d1));+ *+ * std::vector<char> d2(128);+ * bytes_transferred = sock.receive(asio::buffer(d2));+ *+ * std::array<char, 128> d3;+ * bytes_transferred = sock.receive(asio::buffer(d3));+ *+ * boost::array<char, 128> d4;+ * bytes_transferred = sock.receive(asio::buffer(d4)); @endcode+ *+ * In all three cases above, the buffers created are exactly 128 bytes long.+ * Note that a vector is @e never automatically resized when creating or using+ * a buffer. The buffer size is determined using the vector's <tt>size()</tt>+ * member function, and not its capacity.+ *+ * @par Accessing Buffer Contents+ *+ * 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 = b1.size();+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());+ *+ * asio::const_buffer b2 = ...;+ * std::size_t s2 = b2.size();+ * const void* p2 = b2.data(); @endcode+ *+ * The @c data() member function permits violations of type safety, so+ * uses of it in application code should be carefully considered.+ *+ * 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+ *+ * The @ref buffer_copy function may be used to copy raw bytes between+ * individual buffers and buffer sequences.+*+ * In particular, when used with the @ref buffer_size function, the @ref+ * buffer_copy function can be used to linearise a sequence of buffers. For+ * example:+ *+ * @code vector<const_buffer> buffers = ...;+ *+ * vector<unsigned char> data(asio::buffer_size(buffers));+ * asio::buffer_copy(asio::buffer(data), buffers); @endcode+ *+ * Note that @ref buffer_copy is implemented in terms of @c memcpy, and+ * consequently it cannot be used to copy between overlapping memory regions.+ *+ * @par Buffer Invalidation+ *+ * A buffer object does not have any ownership of the memory it refers to. It+ * is the responsibility of the application to ensure the memory region remains+ * valid until it is no longer required for an I/O operation. When the memory+ * is no longer available, the buffer is said to have been invalidated.+ *+ * For the asio::buffer overloads that accept an argument of type+ * std::vector, the buffer objects returned are invalidated by any vector+ * operation that also invalidates all references, pointers and iterators+ * referring to the elements in the sequence (C++ Std, 23.2.4)+ *+ * For the asio::buffer overloads that accept an argument of type+ * std::basic_string, the buffer objects returned are invalidated according to+ * the rules defined for invalidation of references, pointers and iterators+ * referring to elements of the sequence (C++ Std, 21.3).+ *+ * @par Buffer Arithmetic+ *+ * Buffer objects may be manipulated using simple arithmetic in a safe way+ * which helps prevent buffer overruns. Consider an array initialised as+ * follows:+ *+ * @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode+ *+ * A buffer object @c b1 created using:+ *+ * @code b1 = asio::buffer(a); @endcode+ *+ * represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An+ * optional second argument to the asio::buffer function may be used to+ * limit the size, in bytes, of the buffer:+ *+ * @code b2 = asio::buffer(a, 3); @endcode+ *+ * such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the+ * size argument exceeds the actual size of the array, the size of the buffer+ * object created will be limited to the array size.+ *+ * An offset may be applied to an existing buffer to create a new one:+ *+ * @code b3 = b1 + 2; @endcode+ *+ * where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset+ * exceeds the size of the existing buffer, the newly created buffer will be+ * empty.+ *+ * Both an offset and size may be specified to create a buffer that corresponds+ * to a specific range of bytes within an existing buffer:+ *+ * @code b4 = asio::buffer(b1 + 1, 3); @endcode+ *+ * so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>.+ *+ * @par Buffers and Scatter-Gather I/O+ *+ * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple+ * buffer objects may be assigned into a container that supports the+ * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:+ *+ * @code+ * char d1[128];+ * std::vector<char> d2(128);+ * boost::array<char, 128> d3;+ *+ * boost::array<mutable_buffer, 3> bufs1 = {+ *   asio::buffer(d1),+ *   asio::buffer(d2),+ *   asio::buffer(d3) };+ * bytes_transferred = sock.receive(bufs1);+ *+ * std::vector<const_buffer> bufs2;+ * bufs2.push_back(asio::buffer(d1));+ * bufs2.push_back(asio::buffer(d2));+ * bufs2.push_back(asio::buffer(d3));+ * bytes_transferred = sock.send(bufs2); @endcode+ *+ * @par Buffer Literals+ *+ * The `_buf` literal suffix, defined in namespace+ * <tt>asio::buffer_literals</tt>, may be used to create @c const_buffer+ * objects from string, binary integer, and hexadecimal integer literals.+ * For example:+ *+ * @code+ * using namespace asio::buffer_literals;+ *+ * asio::const_buffer b1 = "hello"_buf;+ * asio::const_buffer b2 = 0xdeadbeef_buf;+ * asio::const_buffer b3 = 0x0123456789abcdef0123456789abcdef_buf;+ * asio::const_buffer b4 = 0b1010101011001100_buf; @endcode+ *+ * Note that the memory associated with a buffer literal is valid for the+ * lifetime of the program. This means that the buffer can be safely used with+ * asynchronous operations.+ */+/*@{*/++#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)+# define ASIO_MUTABLE_BUFFER mutable_buffer+# define ASIO_CONST_BUFFER const_buffer+#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)+# define ASIO_MUTABLE_BUFFER mutable_buffers_1+# define ASIO_CONST_BUFFER const_buffers_1+#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)++/// Create a new modifiable buffer from an existing buffer.+/**+ * @returns <tt>mutable_buffer(b)</tt>.+ */+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    const mutable_buffer& b) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(b);+}++/// Create a new modifiable buffer from an existing buffer.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     b.data(),+ *     min(b.size(), max_size_in_bytes)); @endcode+ */+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    const mutable_buffer& b,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(+      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+        ));+}++/// Create a new non-modifiable buffer from an existing buffer.+/**+ * @returns <tt>const_buffer(b)</tt>.+ */+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const const_buffer& b) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(b);+}++/// Create a new non-modifiable buffer from an existing buffer.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     b.data(),+ *     min(b.size(), max_size_in_bytes)); @endcode+ */+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const const_buffer& b,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_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+      );+}++/// Create a new modifiable buffer that represents the given memory range.+/**+ * @returns <tt>mutable_buffer(data, size_in_bytes)</tt>.+ */+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    void* data, std::size_t size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(data, size_in_bytes);+}++/// Create a new non-modifiable buffer that represents the given memory range.+/**+ * @returns <tt>const_buffer(data, size_in_bytes)</tt>.+ */+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const void* data, std::size_t size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data, size_in_bytes);+}++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     static_cast<void*>(data),+ *     N * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    PodType (&data)[N]) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType));+}+ +/// Create a new modifiable buffer that represents the given POD array.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     static_cast<void*>(data),+ *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    PodType (&data)[N],+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(data,+      N * sizeof(PodType) < max_size_in_bytes+      ? N * sizeof(PodType) : max_size_in_bytes);+}+ +/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     static_cast<const void*>(data),+ *     N * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const PodType (&data)[N]) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data, N * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     static_cast<const void*>(data),+ *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const PodType (&data)[N],+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data,+      N * sizeof(PodType) < max_size_in_bytes+      ? N * sizeof(PodType) : max_size_in_bytes);+}++#if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)++// Borland C++ and Sun Studio think the overloads:+//+//   unspecified buffer(boost::array<PodType, N>& array ...);+//+// and+//+//   unspecified buffer(boost::array<const PodType, N>& array ...);+//+// are ambiguous. This will be worked around by using a buffer_types traits+// class that contains typedefs for the appropriate buffer and container+// classes, based on whether PodType is const or non-const.++namespace detail {++template <bool IsConst>+struct buffer_types_base;++template <>+struct buffer_types_base<false>+{+  typedef mutable_buffer buffer_type;+  typedef ASIO_MUTABLE_BUFFER container_type;+};++template <>+struct buffer_types_base<true>+{+  typedef const_buffer buffer_type;+  typedef ASIO_CONST_BUFFER container_type;+};++template <typename PodType>+struct buffer_types+  : public buffer_types_base<is_const<PodType>::value>+{+};++} // namespace detail++template <typename PodType, std::size_t N>+ASIO_NODISCARD inline+typename detail::buffer_types<PodType>::container_type+buffer(boost::array<PodType, N>& data) ASIO_NOEXCEPT+{+  typedef typename asio::detail::buffer_types<PodType>::buffer_type+    buffer_type;+  typedef typename asio::detail::buffer_types<PodType>::container_type+    container_type;+  return container_type(+      buffer_type(data.c_array(), data.size() * sizeof(PodType)));+}++template <typename PodType, std::size_t N>+ASIO_NODISCARD inline+typename detail::buffer_types<PodType>::container_type+buffer(boost::array<PodType, N>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  typedef typename asio::detail::buffer_types<PodType>::buffer_type+    buffer_type;+  typedef typename asio::detail::buffer_types<PodType>::container_type+    container_type;+  return container_type(+      buffer_type(data.c_array(),+        data.size() * sizeof(PodType) < max_size_in_bytes+        ? data.size() * sizeof(PodType) : max_size_in_bytes));+}++#else // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.data(),+ *     data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    boost::array<PodType, N>& data) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(+      data.c_array(), data.size() * sizeof(PodType));+}++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.data(),+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    boost::array<PodType, N>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(data.c_array(),+      data.size() * sizeof(PodType) < max_size_in_bytes+      ? data.size() * sizeof(PodType) : max_size_in_bytes);+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.data(),+ *     data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    boost::array<const PodType, N>& data) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.data(),+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    boost::array<const PodType, N>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(),+      data.size() * sizeof(PodType) < max_size_in_bytes+      ? data.size() * sizeof(PodType) : max_size_in_bytes);+}++#endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.data(),+ *     data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const boost::array<PodType, N>& data) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.data(),+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const boost::array<PodType, N>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(),+      data.size() * sizeof(PodType) < max_size_in_bytes+      ? data.size() * sizeof(PodType) : max_size_in_bytes);+}++#if defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.data(),+ *     data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    std::array<PodType, N>& data) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new modifiable buffer that represents the given POD array.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.data(),+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    std::array<PodType, N>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(data.data(),+      data.size() * sizeof(PodType) < max_size_in_bytes+      ? data.size() * sizeof(PodType) : max_size_in_bytes);+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.data(),+ *     data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    std::array<const PodType, N>& data) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.data(),+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    std::array<const PodType, N>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(),+      data.size() * sizeof(PodType) < max_size_in_bytes+      ? data.size() * sizeof(PodType) : max_size_in_bytes);+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.data(),+ *     data.size() * sizeof(PodType)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const std::array<PodType, N>& data) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));+}++/// Create a new non-modifiable buffer that represents the given POD array.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.data(),+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode+ */+template <typename PodType, std::size_t N>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const std::array<PodType, N>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(),+      data.size() * sizeof(PodType) < max_size_in_bytes+      ? data.size() * sizeof(PodType) : max_size_in_bytes);+}++#endif // defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)++/// Create a new modifiable buffer that represents the given POD vector.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.size() ? &data[0] : 0,+ *     data.size() * sizeof(PodType)); @endcode+ *+ * @note The buffer is invalidated by any vector operation that would also+ * invalidate iterators.+ */+template <typename PodType, typename Allocator>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    std::vector<PodType, Allocator>& data) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(+      data.size() ? &data[0] : 0, data.size() * sizeof(PodType)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename std::vector<PodType, Allocator>::iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new modifiable buffer that represents the given POD vector.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.size() ? &data[0] : 0,+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode+ *+ * @note The buffer is invalidated by any vector operation that would also+ * invalidate iterators.+ */+template <typename PodType, typename Allocator>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    std::vector<PodType, Allocator>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,+      data.size() * sizeof(PodType) < max_size_in_bytes+      ? data.size() * sizeof(PodType) : max_size_in_bytes+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename std::vector<PodType, Allocator>::iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new non-modifiable buffer that represents the given POD vector.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.size() ? &data[0] : 0,+ *     data.size() * sizeof(PodType)); @endcode+ *+ * @note The buffer is invalidated by any vector operation that would also+ * invalidate iterators.+ */+template <typename PodType, typename Allocator>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const std::vector<PodType, Allocator>& data) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(+      data.size() ? &data[0] : 0, data.size() * sizeof(PodType)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename std::vector<PodType, Allocator>::const_iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new non-modifiable buffer that represents the given POD vector.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.size() ? &data[0] : 0,+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode+ *+ * @note The buffer is invalidated by any vector operation that would also+ * invalidate iterators.+ */+template <typename PodType, typename Allocator>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const std::vector<PodType, Allocator>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,+      data.size() * sizeof(PodType) < max_size_in_bytes+      ? data.size() * sizeof(PodType) : max_size_in_bytes+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename std::vector<PodType, Allocator>::const_iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new modifiable buffer that represents the given string.+/**+ * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,+ * data.size() * sizeof(Elem))</tt>.+ *+ * @note The buffer is invalidated by any non-const operation called on the+ * given string object.+ */+template <typename Elem, typename Traits, typename Allocator>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    std::basic_string<Elem, Traits, Allocator>& data) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,+      data.size() * sizeof(Elem)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename std::basic_string<Elem, Traits, Allocator>::iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new modifiable buffer that represents the given string.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.size() ? &data[0] : 0,+ *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode+ *+ * @note The buffer is invalidated by any non-const operation called on the+ * given string object.+ */+template <typename Elem, typename Traits, typename Allocator>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    std::basic_string<Elem, Traits, Allocator>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,+      data.size() * sizeof(Elem) < max_size_in_bytes+      ? data.size() * sizeof(Elem) : max_size_in_bytes+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename std::basic_string<Elem, Traits, Allocator>::iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new non-modifiable buffer that represents the given string.+/**+ * @returns <tt>const_buffer(data.data(), data.size() * sizeof(Elem))</tt>.+ *+ * @note The buffer is invalidated by any non-const operation called on the+ * given string object.+ */+template <typename Elem, typename Traits, typename Allocator>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const std::basic_string<Elem, Traits, Allocator>& data) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename std::basic_string<Elem, Traits, Allocator>::const_iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new non-modifiable buffer that represents the given string.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.data(),+ *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode+ *+ * @note The buffer is invalidated by any non-const operation called on the+ * given string object.+ */+template <typename Elem, typename Traits, typename Allocator>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const std::basic_string<Elem, Traits, Allocator>& data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.data(),+      data.size() * sizeof(Elem) < max_size_in_bytes+      ? data.size() * sizeof(Elem) : max_size_in_bytes+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename std::basic_string<Elem, Traits, Allocator>::const_iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++#if defined(ASIO_HAS_STRING_VIEW) \+  || defined(GENERATING_DOCUMENTATION)++/// Create a new non-modifiable buffer that represents the given string_view.+/**+ * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,+ * data.size() * sizeof(Elem))</tt>.+ */+template <typename Elem, typename Traits>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    basic_string_view<Elem, Traits> data) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,+      data.size() * sizeof(Elem)+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename basic_string_view<Elem, Traits>::iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++/// Create a new non-modifiable buffer that represents the given string.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.size() ? &data[0] : 0,+ *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode+ */+template <typename Elem, typename Traits>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    basic_string_view<Elem, Traits> data,+    std::size_t max_size_in_bytes) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,+      data.size() * sizeof(Elem) < max_size_in_bytes+      ? data.size() * sizeof(Elem) : max_size_in_bytes+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)+      , detail::buffer_debug_check<+          typename basic_string_view<Elem, Traits>::iterator+        >(data.begin())+#endif // ASIO_ENABLE_BUFFER_DEBUGGING+      );+}++#endif // defined(ASIO_HAS_STRING_VIEW)+       //  || defined(GENERATING_DOCUMENTATION)++/// Create a new modifiable buffer from a contiguous container.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.size() ? &data[0] : 0,+ *     data.size() * sizeof(typename T::value_type)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    T& data,+    typename constraint<+      is_contiguous_iterator<typename T::iterator>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, const_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, mutable_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_const<+        typename remove_reference<+          typename std::iterator_traits<typename T::iterator>::reference+        >::type+      >::value,+      defaulted_constraint+    >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(+      data.size() ? detail::to_address(data.begin()) : 0,+      data.size() * sizeof(typename T::value_type));+}++/// Create a new modifiable buffer from a contiguous container.+/**+ * @returns A mutable_buffer value equivalent to:+ * @code mutable_buffer(+ *     data.size() ? &data[0] : 0,+ *     min(+ *       data.size() * sizeof(typename T::value_type),+ *       max_size_in_bytes)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_MUTABLE_BUFFER buffer(+    T& data, std::size_t max_size_in_bytes,+    typename constraint<+      is_contiguous_iterator<typename T::iterator>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, const_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, mutable_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_const<+        typename remove_reference<+          typename std::iterator_traits<typename T::iterator>::reference+        >::type+      >::value,+      defaulted_constraint+    >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+  return ASIO_MUTABLE_BUFFER(+      data.size() ? detail::to_address(data.begin()) : 0,+      data.size() * sizeof(typename T::value_type) < max_size_in_bytes+      ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);+}++/// Create a new non-modifiable buffer from a contiguous container.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.size() ? &data[0] : 0,+ *     data.size() * sizeof(typename T::value_type)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    T& data,+    typename constraint<+      is_contiguous_iterator<typename T::iterator>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, const_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, mutable_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      is_const<+        typename remove_reference<+          typename std::iterator_traits<typename T::iterator>::reference+        >::type+      >::value,+      defaulted_constraint+    >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(+      data.size() ? detail::to_address(data.begin()) : 0,+      data.size() * sizeof(typename T::value_type));+}++/// Create a new non-modifiable buffer from a contiguous container.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.size() ? &data[0] : 0,+ *     min(+ *       data.size() * sizeof(typename T::value_type),+ *       max_size_in_bytes)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    T& data, std::size_t max_size_in_bytes,+    typename constraint<+      is_contiguous_iterator<typename T::iterator>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, const_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, mutable_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      is_const<+        typename remove_reference<+          typename std::iterator_traits<typename T::iterator>::reference+        >::type+      >::value,+      defaulted_constraint+    >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(+      data.size() ? detail::to_address(data.begin()) : 0,+      data.size() * sizeof(typename T::value_type) < max_size_in_bytes+      ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);+}++/// Create a new non-modifiable buffer from a contiguous container.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.size() ? &data[0] : 0,+ *     data.size() * sizeof(typename T::value_type)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const T& data,+    typename constraint<+      is_contiguous_iterator<typename T::const_iterator>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, const_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, mutable_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(+      data.size() ? detail::to_address(data.begin()) : 0,+      data.size() * sizeof(typename T::value_type));+}++/// Create a new non-modifiable buffer from a contiguous container.+/**+ * @returns A const_buffer value equivalent to:+ * @code const_buffer(+ *     data.size() ? &data[0] : 0,+ *     min(+ *       data.size() * sizeof(typename T::value_type),+ *       max_size_in_bytes)); @endcode+ */+template <typename T>+ASIO_NODISCARD inline ASIO_CONST_BUFFER buffer(+    const T& data, std::size_t max_size_in_bytes,+    typename constraint<+      is_contiguous_iterator<typename T::const_iterator>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, const_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint(),+    typename constraint<+      !is_convertible<T, mutable_buffer>::value,+      defaulted_constraint+    >::type = defaulted_constraint()) ASIO_NOEXCEPT+{+  return ASIO_CONST_BUFFER(+      data.size() ? detail::to_address(data.begin()) : 0,+      data.size() * sizeof(typename T::value_type) < max_size_in_bytes+      ? data.size() * sizeof(typename T::value_type) : max_size_in_bytes);+}++/*@}*/++/// Adapt a basic_string to the DynamicBuffer requirements.+/**+ * Requires that <tt>sizeof(Elem) == 1</tt>.+ */+template <typename Elem, typename Traits, typename Allocator>+class dynamic_string_buffer+{+public:+  /// The type used to represent a sequence of constant buffers that refers to+  /// the underlying memory.+  typedef ASIO_CONST_BUFFER const_buffers_type;++  /// The type used to represent a sequence of mutable buffers that refers to+  /// the underlying memory.+  typedef ASIO_MUTABLE_BUFFER mutable_buffers_type;++  /// Construct a dynamic buffer from a string.+  /**+   * @param s The string to be used as backing storage for the dynamic buffer.+   * The object stores a reference to the string and the user is responsible+   * for ensuring that the string object remains valid while the+   * dynamic_string_buffer object, and copies of the object, are in use.+   *+   * @b DynamicBuffer_v1: Any existing data in the string is treated as the+   * dynamic buffer's input sequence.+   *+   * @param maximum_size Specifies a maximum size for the buffer, in bytes.+   */+  explicit dynamic_string_buffer(std::basic_string<Elem, Traits, Allocator>& s,+      std::size_t maximum_size =+        (std::numeric_limits<std::size_t>::max)()) ASIO_NOEXCEPT+    : string_(s),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      size_((std::numeric_limits<std::size_t>::max)()),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      max_size_(maximum_size)+  {+  }++  /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.+  dynamic_string_buffer(const dynamic_string_buffer& other) ASIO_NOEXCEPT+    : string_(other.string_),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      size_(other.size_),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      max_size_(other.max_size_)+  {+  }++#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+  /// Move construct a dynamic buffer.+  dynamic_string_buffer(dynamic_string_buffer&& other) ASIO_NOEXCEPT+    : string_(other.string_),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      size_(other.size_),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      max_size_(other.max_size_)+  {+  }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++  /// @b DynamicBuffer_v1: Get the size of the input sequence.+  /// @b DynamicBuffer_v2: Get the current size of the underlying memory.+  /**+   * @returns @b DynamicBuffer_v1 The current size of the input sequence.+   * @b DynamicBuffer_v2: The current size of the underlying string if less than+   * max_size(). Otherwise returns max_size().+   */+  std::size_t size() const ASIO_NOEXCEPT+  {+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+    if (size_ != (std::numeric_limits<std::size_t>::max)())+      return size_;+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+    return (std::min)(string_.size(), max_size());+  }++  /// Get the maximum size of the dynamic buffer.+  /**+   * @returns The allowed maximum size of the underlying memory.+   */+  std::size_t max_size() const ASIO_NOEXCEPT+  {+    return max_size_;+  }++  /// Get the maximum size that the buffer may grow to without triggering+  /// reallocation.+  /**+   * @returns The current capacity of the underlying string if less than+   * max_size(). Otherwise returns max_size().+   */+  std::size_t capacity() const ASIO_NOEXCEPT+  {+    return (std::min)(string_.capacity(), max_size());+  }++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  /// @b DynamicBuffer_v1: Get a list of buffers that represents the input+  /// sequence.+  /**+   * @returns An object of type @c const_buffers_type that satisfies+   * ConstBufferSequence requirements, representing the basic_string memory in+   * the input sequence.+   *+   * @note The returned object is invalidated by any @c dynamic_string_buffer+   * or @c basic_string member function that resizes or erases the string.+   */+  const_buffers_type data() const ASIO_NOEXCEPT+  {+    return const_buffers_type(asio::buffer(string_, size_));+  }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++  /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the+  /// underlying memory.+  /**+   * @param pos Position of the first byte to represent in the buffer sequence+   *+   * @param n The number of bytes to return in the buffer sequence. If the+   * underlying memory is shorter, the buffer sequence represents as many bytes+   * as are available.+   *+   * @returns An object of type @c mutable_buffers_type that satisfies+   * MutableBufferSequence requirements, representing the basic_string memory.+   *+   * @note The returned object is invalidated by any @c dynamic_string_buffer+   * or @c basic_string member function that resizes or erases the string.+   */+  mutable_buffers_type data(std::size_t pos, std::size_t n) ASIO_NOEXCEPT+  {+    return mutable_buffers_type(asio::buffer(+          asio::buffer(string_, max_size_) + pos, n));+  }++  /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the+  /// underlying memory.+  /**+   * @param pos Position of the first byte to represent in the buffer sequence+   *+   * @param n The number of bytes to return in the buffer sequence. If the+   * underlying memory is shorter, the buffer sequence represents as many bytes+   * as are available.+   *+   * @note The returned object is invalidated by any @c dynamic_string_buffer+   * or @c basic_string member function that resizes or erases the string.+   */+  const_buffers_type data(std::size_t pos,+      std::size_t n) const ASIO_NOEXCEPT+  {+    return const_buffers_type(asio::buffer(+          asio::buffer(string_, max_size_) + pos, n));+  }++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  /// @b DynamicBuffer_v1: Get a list of buffers that represents the output+  /// sequence, with the given size.+  /**+   * Ensures that the output sequence can accommodate @c n bytes, resizing the+   * basic_string object as necessary.+   *+   * @returns An object of type @c mutable_buffers_type that satisfies+   * MutableBufferSequence requirements, representing basic_string memory+   * at the start of the output sequence of size @c n.+   *+   * @throws std::length_error If <tt>size() + n > max_size()</tt>.+   *+   * @note The returned object is invalidated by any @c dynamic_string_buffer+   * or @c basic_string member function that modifies the input sequence or+   * output sequence.+   */+  mutable_buffers_type prepare(std::size_t n)+  {+    if (size() > max_size() || max_size() - size() < n)+    {+      std::length_error ex("dynamic_string_buffer too long");+      asio::detail::throw_exception(ex);+    }++    if (size_ == (std::numeric_limits<std::size_t>::max)())+      size_ = string_.size(); // Enable v1 behaviour.++    string_.resize(size_ + n);++    return asio::buffer(asio::buffer(string_) + size_, n);+  }++  /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input+  /// sequence.+  /**+   * @param n The number of bytes to append from the start of the output+   * sequence to the end of the input sequence. The remainder of the output+   * sequence is discarded.+   *+   * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and+   * no intervening operations that modify the input or output sequence.+   *+   * @note If @c n is greater than the size of the output sequence, the entire+   * output sequence is moved to the input sequence and no error is issued.+   */+  void commit(std::size_t n)+  {+    size_ += (std::min)(n, string_.size() - size_);+    string_.resize(size_);+  }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++  /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of+  /// bytes.+  /**+   * Resizes the string to accommodate an additional @c n bytes at the end.+   *+   * @throws std::length_error If <tt>size() + n > max_size()</tt>.+   */+  void grow(std::size_t n)+  {+    if (size() > max_size() || max_size() - size() < n)+    {+      std::length_error ex("dynamic_string_buffer too long");+      asio::detail::throw_exception(ex);+    }++    string_.resize(size() + n);+  }++  /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number+  /// of bytes.+  /**+   * Erases @c n bytes from the end of the string by resizing the basic_string+   * object. If @c n is greater than the current size of the string, the string+   * is emptied.+   */+  void shrink(std::size_t n)+  {+    string_.resize(n > size() ? 0 : size() - n);+  }++  /// @b DynamicBuffer_v1: Remove characters from the input sequence.+  /// @b DynamicBuffer_v2: Consume the specified number of bytes from the+  /// beginning of the underlying memory.+  /**+   * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the+   * input sequence. @note If @c n is greater than the size of the input+   * sequence, the entire input sequence is consumed and no error is issued.+   *+   * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the string.+   * If @c n is greater than the current size of the string, the string is+   * emptied.+   */+  void consume(std::size_t n)+  {+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+    if (size_ != (std::numeric_limits<std::size_t>::max)())+    {+      std::size_t consume_length = (std::min)(n, size_);+      string_.erase(0, consume_length);+      size_ -= consume_length;+      return;+    }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+    string_.erase(0, n);+  }++private:+  std::basic_string<Elem, Traits, Allocator>& string_;+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  std::size_t size_;+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  const std::size_t max_size_;+};++/// Adapt a vector to the DynamicBuffer requirements.+/**+ * Requires that <tt>sizeof(Elem) == 1</tt>.+ */+template <typename Elem, typename Allocator>+class dynamic_vector_buffer+{+public:+  /// The type used to represent a sequence of constant buffers that refers to+  /// the underlying memory.+  typedef ASIO_CONST_BUFFER const_buffers_type;++  /// The type used to represent a sequence of mutable buffers that refers to+  /// the underlying memory.+  typedef ASIO_MUTABLE_BUFFER mutable_buffers_type;++  /// Construct a dynamic buffer from a vector.+  /**+   * @param v The vector to be used as backing storage for the dynamic buffer.+   * The object stores a reference to the vector and the user is responsible+   * for ensuring that the vector object remains valid while the+   * dynamic_vector_buffer object, and copies of the object, are in use.+   *+   * @param maximum_size Specifies a maximum size for the buffer, in bytes.+   */+  explicit dynamic_vector_buffer(std::vector<Elem, Allocator>& v,+      std::size_t maximum_size =+        (std::numeric_limits<std::size_t>::max)()) ASIO_NOEXCEPT+    : vector_(v),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      size_((std::numeric_limits<std::size_t>::max)()),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      max_size_(maximum_size)+  {+  }++  /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.+  dynamic_vector_buffer(const dynamic_vector_buffer& other) ASIO_NOEXCEPT+    : vector_(other.vector_),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      size_(other.size_),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      max_size_(other.max_size_)+  {+  }++#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+  /// Move construct a dynamic buffer.+  dynamic_vector_buffer(dynamic_vector_buffer&& other) ASIO_NOEXCEPT+    : vector_(other.vector_),+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      size_(other.size_),+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+      max_size_(other.max_size_)+  {+  }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++  /// @b DynamicBuffer_v1: Get the size of the input sequence.+  /// @b DynamicBuffer_v2: Get the current size of the underlying memory.+  /**+   * @returns @b DynamicBuffer_v1 The current size of the input sequence.+   * @b DynamicBuffer_v2: The current size of the underlying vector if less than+   * max_size(). Otherwise returns max_size().+   */+  std::size_t size() const ASIO_NOEXCEPT+  {+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+    if (size_ != (std::numeric_limits<std::size_t>::max)())+      return size_;+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+    return (std::min)(vector_.size(), max_size());+  }++  /// Get the maximum size of the dynamic buffer.+  /**+   * @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes+   * of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed+   * maximum size of the underlying memory.+   */+  std::size_t max_size() const ASIO_NOEXCEPT+  {+    return max_size_;+  }++  /// Get the maximum size that the buffer may grow to without triggering+  /// reallocation.+  /**+   * @returns @b DynamicBuffer_v1: The current total capacity of the buffer,+   * i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2:+   * The current capacity of the underlying vector if less than max_size().+   * Otherwise returns max_size().+   */+  std::size_t capacity() const ASIO_NOEXCEPT+  {+    return (std::min)(vector_.capacity(), max_size());+  }++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  /// @b DynamicBuffer_v1: Get a list of buffers that represents the input+  /// sequence.+  /**+   * @returns An object of type @c const_buffers_type that satisfies+   * ConstBufferSequence requirements, representing the vector memory in the+   * input sequence.+   *+   * @note The returned object is invalidated by any @c dynamic_vector_buffer+   * or @c vector member function that modifies the input sequence or output+   * sequence.+   */+  const_buffers_type data() const ASIO_NOEXCEPT+  {+    return const_buffers_type(asio::buffer(vector_, size_));+  }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++  /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the+  /// underlying memory.+  /**+   * @param pos Position of the first byte to represent in the buffer sequence+   *+   * @param n The number of bytes to return in the buffer sequence. If the+   * underlying memory is shorter, the buffer sequence represents as many bytes+   * as are available.+   *+   * @returns An object of type @c mutable_buffers_type that satisfies+   * MutableBufferSequence requirements, representing the vector memory.+   *+   * @note The returned object is invalidated by any @c dynamic_vector_buffer+   * or @c vector member function that resizes or erases the vector.+   */+  mutable_buffers_type data(std::size_t pos, std::size_t n) ASIO_NOEXCEPT+  {+    return mutable_buffers_type(asio::buffer(+          asio::buffer(vector_, max_size_) + pos, n));+  }++  /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the+  /// underlying memory.+  /**+   * @param pos Position of the first byte to represent in the buffer sequence+   *+   * @param n The number of bytes to return in the buffer sequence. If the+   * underlying memory is shorter, the buffer sequence represents as many bytes+   * as are available.+   *+   * @note The returned object is invalidated by any @c dynamic_vector_buffer+   * or @c vector member function that resizes or erases the vector.+   */+  const_buffers_type data(std::size_t pos,+      std::size_t n) const ASIO_NOEXCEPT+  {+    return const_buffers_type(asio::buffer(+          asio::buffer(vector_, max_size_) + pos, n));+  }++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  /// @b DynamicBuffer_v1: Get a list of buffers that represents the output+  /// sequence, with the given size.+  /**+   * Ensures that the output sequence can accommodate @c n bytes, resizing the+   * vector object as necessary.+   *+   * @returns An object of type @c mutable_buffers_type that satisfies+   * MutableBufferSequence requirements, representing vector memory at the+   * start of the output sequence of size @c n.+   *+   * @throws std::length_error If <tt>size() + n > max_size()</tt>.+   *+   * @note The returned object is invalidated by any @c dynamic_vector_buffer+   * or @c vector member function that modifies the input sequence or output+   * sequence.+   */+  mutable_buffers_type prepare(std::size_t n)+  {+    if (size () > max_size() || max_size() - size() < n)+    {+      std::length_error ex("dynamic_vector_buffer too long");+      asio::detail::throw_exception(ex);+    }++    if (size_ == (std::numeric_limits<std::size_t>::max)())+      size_ = vector_.size(); // Enable v1 behaviour.++    vector_.resize(size_ + n);++    return asio::buffer(asio::buffer(vector_) + size_, n);+  }++  /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input+  /// sequence.+  /**+   * @param n The number of bytes to append from the start of the output+   * sequence to the end of the input sequence. The remainder of the output+   * sequence is discarded.+   *+   * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and+   * no intervening operations that modify the input or output sequence.+   *+   * @note If @c n is greater than the size of the output sequence, the entire+   * output sequence is moved to the input sequence and no error is issued.+   */+  void commit(std::size_t n)+  {+    size_ += (std::min)(n, vector_.size() - size_);+    vector_.resize(size_);+  }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++  /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of+  /// bytes.+  /**+   * Resizes the vector to accommodate an additional @c n bytes at the end.+   *+   * @throws std::length_error If <tt>size() + n > max_size()</tt>.+   */+  void grow(std::size_t n)+  {+    if (size() > max_size() || max_size() - size() < n)+    {+      std::length_error ex("dynamic_vector_buffer too long");+      asio::detail::throw_exception(ex);+    }++    vector_.resize(size() + n);+  }++  /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number+  /// of bytes.+  /**+   * Erases @c n bytes from the end of the vector by resizing the vector+   * object. If @c n is greater than the current size of the vector, the vector+   * is emptied.+   */+  void shrink(std::size_t n)+  {+    vector_.resize(n > size() ? 0 : size() - n);+  }++  /// @b DynamicBuffer_v1: Remove characters from the input sequence.+  /// @b DynamicBuffer_v2: Consume the specified number of bytes from the+  /// beginning of the underlying memory.+  /**+   * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the+   * input sequence. @note If @c n is greater than the size of the input+   * sequence, the entire input sequence is consumed and no error is issued.+   *+   * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the vector.+   * If @c n is greater than the current size of the vector, the vector is+   * emptied.+   */+  void consume(std::size_t n)+  {+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+    if (size_ != (std::numeric_limits<std::size_t>::max)())+    {+      std::size_t consume_length = (std::min)(n, size_);+      vector_.erase(vector_.begin(), vector_.begin() + consume_length);+      size_ -= consume_length;+      return;+    }+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+    vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n));+  }++private:+  std::vector<Elem, Allocator>& vector_;+#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  std::size_t size_;+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  const std::size_t max_size_;+};++/** @defgroup dynamic_buffer asio::dynamic_buffer+ *+ * @brief The asio::dynamic_buffer function is used to create a+ * dynamically resized buffer from a @c std::basic_string or @c std::vector.+ */+/*@{*/++/// Create a new dynamic buffer that represents the given string.+/**+ * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data)</tt>.+ */+template <typename Elem, typename Traits, typename Allocator>+ASIO_NODISCARD inline+dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(+    std::basic_string<Elem, Traits, Allocator>& data) ASIO_NOEXCEPT+{+  return dynamic_string_buffer<Elem, Traits, Allocator>(data);+}++/// Create a new dynamic buffer that represents the given string.+/**+ * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data,+ * max_size)</tt>.+ */+template <typename Elem, typename Traits, typename Allocator>+ASIO_NODISCARD inline+dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(+    std::basic_string<Elem, Traits, Allocator>& data,+    std::size_t max_size) ASIO_NOEXCEPT+{+  return dynamic_string_buffer<Elem, Traits, Allocator>(data, max_size);+}++/// Create a new dynamic buffer that represents the given vector.+/**+ * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data)</tt>.+ */+template <typename Elem, typename Allocator>+ASIO_NODISCARD inline+dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(+    std::vector<Elem, Allocator>& data) ASIO_NOEXCEPT+{+  return dynamic_vector_buffer<Elem, Allocator>(data);+}++/// Create a new dynamic buffer that represents the given vector.+/**+ * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data, max_size)</tt>.+ */+template <typename Elem, typename Allocator>+ASIO_NODISCARD inline+dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(+    std::vector<Elem, Allocator>& data,+    std::size_t max_size) ASIO_NOEXCEPT+{+  return dynamic_vector_buffer<Elem, Allocator>(data, max_size);+}++/*@}*/++/** @defgroup buffer_copy asio::buffer_copy+ *+ * @brief The asio::buffer_copy function is used to copy bytes from a+ * source buffer (or buffer sequence) to a target buffer (or buffer sequence).+ *+ * The @c buffer_copy function is available in two forms:+ *+ * @li A 2-argument form: @c buffer_copy(target, source)+ *+ * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy)+ *+ * Both forms return the number of bytes actually copied. The number of bytes+ * copied is the lesser of:+ *+ * @li @c buffer_size(target)+ *+ * @li @c buffer_size(source)+ *+ * @li @c If specified, @c max_bytes_to_copy.+ *+ * This prevents buffer overflow, regardless of the buffer sizes used in the+ * copy operation.+ *+ * Note that @ref buffer_copy is implemented in terms of @c memcpy, and+ * consequently it cannot be used to copy between overlapping memory regions.+ */+/*@{*/++namespace detail {++inline std::size_t buffer_copy_1(const mutable_buffer& target,+    const const_buffer& source)+{+  using namespace std; // For memcpy.+  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;+  if (n > 0)+    memcpy(target.data(), source.data(), n);+  return n;+}++template <typename TargetIterator, typename SourceIterator>+inline std::size_t buffer_copy(one_buffer, one_buffer,+    TargetIterator target_begin, TargetIterator,+    SourceIterator source_begin, SourceIterator) ASIO_NOEXCEPT+{+  return (buffer_copy_1)(*target_begin, *source_begin);+}++template <typename TargetIterator, typename SourceIterator>+inline std::size_t buffer_copy(one_buffer, one_buffer,+    TargetIterator target_begin, TargetIterator,+    SourceIterator source_begin, SourceIterator,+    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT+{+  return (buffer_copy_1)(*target_begin,+      asio::buffer(*source_begin, max_bytes_to_copy));+}++template <typename TargetIterator, typename SourceIterator>+std::size_t buffer_copy(one_buffer, multiple_buffers,+    TargetIterator target_begin, TargetIterator,+    SourceIterator source_begin, SourceIterator source_end,+    std::size_t max_bytes_to_copy+      = (std::numeric_limits<std::size_t>::max)()) ASIO_NOEXCEPT+{+  std::size_t total_bytes_copied = 0;+  SourceIterator source_iter = source_begin;++  for (mutable_buffer target_buffer(+        asio::buffer(*target_begin, max_bytes_to_copy));+      target_buffer.size() && source_iter != source_end; ++source_iter)+  {+    const_buffer source_buffer(*source_iter);+    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);+    total_bytes_copied += bytes_copied;+    target_buffer += bytes_copied;+  }++  return total_bytes_copied;+}++template <typename TargetIterator, typename SourceIterator>+std::size_t buffer_copy(multiple_buffers, one_buffer,+    TargetIterator target_begin, TargetIterator target_end,+    SourceIterator source_begin, SourceIterator,+    std::size_t max_bytes_to_copy+      = (std::numeric_limits<std::size_t>::max)()) ASIO_NOEXCEPT+{+  std::size_t total_bytes_copied = 0;+  TargetIterator target_iter = target_begin;++  for (const_buffer source_buffer(+        asio::buffer(*source_begin, max_bytes_to_copy));+      source_buffer.size() && target_iter != target_end; ++target_iter)+  {+    mutable_buffer target_buffer(*target_iter);+    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);+    total_bytes_copied += bytes_copied;+    source_buffer += bytes_copied;+  }++  return total_bytes_copied;+}++template <typename TargetIterator, typename SourceIterator>+std::size_t buffer_copy(multiple_buffers, multiple_buffers,+    TargetIterator target_begin, TargetIterator target_end,+    SourceIterator source_begin, SourceIterator source_end) ASIO_NOEXCEPT+{+  std::size_t total_bytes_copied = 0;++  TargetIterator target_iter = target_begin;+  std::size_t target_buffer_offset = 0;++  SourceIterator source_iter = source_begin;+  std::size_t source_buffer_offset = 0;++  while (target_iter != target_end && source_iter != source_end)+  {+    mutable_buffer target_buffer =+      mutable_buffer(*target_iter) + target_buffer_offset;++    const_buffer source_buffer =+      const_buffer(*source_iter) + source_buffer_offset;++    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);+    total_bytes_copied += bytes_copied;++    if (bytes_copied == target_buffer.size())+    {+      ++target_iter;+      target_buffer_offset = 0;+    }+    else+      target_buffer_offset += bytes_copied;++    if (bytes_copied == source_buffer.size())+    {+      ++source_iter;+      source_buffer_offset = 0;+    }+    else+      source_buffer_offset += bytes_copied;+  }++  return total_bytes_copied;+}++template <typename TargetIterator, typename SourceIterator>+std::size_t buffer_copy(multiple_buffers, multiple_buffers,+    TargetIterator target_begin, TargetIterator target_end,+    SourceIterator source_begin, SourceIterator source_end,+    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT+{+  std::size_t total_bytes_copied = 0;++  TargetIterator target_iter = target_begin;+  std::size_t target_buffer_offset = 0;++  SourceIterator source_iter = source_begin;+  std::size_t source_buffer_offset = 0;++  while (total_bytes_copied != max_bytes_to_copy+      && target_iter != target_end && source_iter != source_end)+  {+    mutable_buffer target_buffer =+      mutable_buffer(*target_iter) + target_buffer_offset;++    const_buffer source_buffer =+      const_buffer(*source_iter) + source_buffer_offset;++    std::size_t bytes_copied = (buffer_copy_1)(+        target_buffer, asio::buffer(source_buffer,+          max_bytes_to_copy - total_bytes_copied));+    total_bytes_copied += bytes_copied;++    if (bytes_copied == target_buffer.size())+    {+      ++target_iter;+      target_buffer_offset = 0;+    }+    else+      target_buffer_offset += bytes_copied;++    if (bytes_copied == source_buffer.size())+    {+      ++source_iter;+      source_buffer_offset = 0;+    }+    else+      source_buffer_offset += bytes_copied;+  }++  return total_bytes_copied;+}++} // namespace detail++/// Copies bytes from a source buffer sequence to a target buffer sequence.+/**+ * @param target A modifiable buffer sequence representing the memory regions to+ * which the bytes will be copied.+ *+ * @param source A non-modifiable buffer sequence representing the memory+ * regions from which the bytes will be copied.+ *+ * @returns The number of bytes copied.+ *+ * @note The number of bytes copied is the lesser of:+ *+ * @li @c buffer_size(target)+ *+ * @li @c buffer_size(source)+ *+ * This function is implemented in terms of @c memcpy, and consequently it+ * cannot be used to copy between overlapping memory regions.+ */+template <typename MutableBufferSequence, typename ConstBufferSequence>+inline std::size_t buffer_copy(const MutableBufferSequence& target,+    const ConstBufferSequence& source) ASIO_NOEXCEPT+{+  return detail::buffer_copy(+      detail::buffer_sequence_cardinality<MutableBufferSequence>(),+      detail::buffer_sequence_cardinality<ConstBufferSequence>(),+      asio::buffer_sequence_begin(target),+      asio::buffer_sequence_end(target),+      asio::buffer_sequence_begin(source),+      asio::buffer_sequence_end(source));+}++/// Copies a limited number of bytes from a source buffer sequence to a target+/// buffer sequence.+/**+ * @param target A modifiable buffer sequence representing the memory regions to+ * which the bytes will be copied.+ *+ * @param source A non-modifiable buffer sequence representing the memory+ * regions from which the bytes will be copied.+ *+ * @param max_bytes_to_copy The maximum number of bytes to be copied.+ *+ * @returns The number of bytes copied.+ *+ * @note The number of bytes copied is the lesser of:+ *+ * @li @c buffer_size(target)+ *+ * @li @c buffer_size(source)+ *+ * @li @c max_bytes_to_copy+ *+ * This function is implemented in terms of @c memcpy, and consequently it+ * cannot be used to copy between overlapping memory regions.+ */+template <typename MutableBufferSequence, typename ConstBufferSequence>+inline std::size_t buffer_copy(const MutableBufferSequence& target,+    const ConstBufferSequence& source,+    std::size_t max_bytes_to_copy) ASIO_NOEXCEPT+{+  return detail::buffer_copy(+      detail::buffer_sequence_cardinality<MutableBufferSequence>(),+      detail::buffer_sequence_cardinality<ConstBufferSequence>(),+      asio::buffer_sequence_begin(target),+      asio::buffer_sequence_end(target),+      asio::buffer_sequence_begin(source),+      asio::buffer_sequence_end(source), max_bytes_to_copy);+}++/*@}*/++} // namespace asio++#include "asio/detail/pop_options.hpp"+#include "asio/detail/is_buffer_sequence.hpp"+#include "asio/detail/push_options.hpp"++namespace asio {++/// Trait to determine whether a type satisfies the MutableBufferSequence+/// requirements.+template <typename T>+struct is_mutable_buffer_sequence+#if defined(GENERATING_DOCUMENTATION)+  : integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  : asio::detail::is_buffer_sequence<T, mutable_buffer>+#endif // defined(GENERATING_DOCUMENTATION)+{+};++/// Trait to determine whether a type satisfies the ConstBufferSequence+/// requirements.+template <typename T>+struct is_const_buffer_sequence+#if defined(GENERATING_DOCUMENTATION)+  : integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  : asio::detail::is_buffer_sequence<T, const_buffer>+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)+/// Trait to determine whether a type satisfies the DynamicBuffer_v1+/// requirements.+template <typename T>+struct is_dynamic_buffer_v1+#if defined(GENERATING_DOCUMENTATION)+  : integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  : asio::detail::is_dynamic_buffer_v1<T>+#endif // defined(GENERATING_DOCUMENTATION)+{+};+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++/// Trait to determine whether a type satisfies the DynamicBuffer_v2+/// requirements.+template <typename T>+struct is_dynamic_buffer_v2+#if defined(GENERATING_DOCUMENTATION)+  : integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  : asio::detail::is_dynamic_buffer_v2<T>+#endif // defined(GENERATING_DOCUMENTATION)+{+};++/// Trait to determine whether a type satisfies the DynamicBuffer requirements.+/**+ * If @c ASIO_NO_DYNAMIC_BUFFER_V1 is not defined, determines whether the+ * type satisfies the DynamicBuffer_v1 requirements. Otherwise, if @c+ * ASIO_NO_DYNAMIC_BUFFER_V1 is defined, determines whether the type+ * satisfies the DynamicBuffer_v2 requirements.+ */+template <typename T>+struct is_dynamic_buffer+#if defined(GENERATING_DOCUMENTATION)+  : integral_constant<bool, automatically_determined>+#elif defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  : asio::is_dynamic_buffer_v2<T>+#else // defined(ASIO_NO_DYNAMIC_BUFFER_V1)+  : asio::is_dynamic_buffer_v1<T>+#endif // defined(ASIO_NO_DYNAMIC_BUFFER_V1)+{+};++#if (defined(ASIO_HAS_USER_DEFINED_LITERALS) \+    && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+  || defined(GENERATING_DOCUMENTATION)++namespace buffer_literals {+namespace detail {++template <char... Chars>+struct chars {};++template <unsigned char... Bytes>+struct bytes {};++// Literal processor that converts binary literals to an array of bytes.++template <typename Bytes, char... Chars>+struct bin_literal;++template <unsigned char... Bytes>+struct bin_literal<bytes<Bytes...> >+{+  static const std::size_t size = sizeof...(Bytes);+  static const unsigned char data[sizeof...(Bytes)];+};++template <unsigned char... Bytes>+const unsigned char bin_literal<bytes<Bytes...> >::data[sizeof...(Bytes)]+  = { Bytes... };++template <unsigned char... Bytes, char Bit7, char Bit6, char Bit5,+    char Bit4, char Bit3, char Bit2, char Bit1, char Bit0, char... Chars>+struct bin_literal<bytes<Bytes...>, Bit7, Bit6,+    Bit5, Bit4, Bit3, Bit2, Bit1, Bit0, Chars...> :+  bin_literal<+    bytes<Bytes...,+      static_cast<unsigned char>(+      (Bit7 == '1' ? 0x80 : 0) |+        (Bit6 == '1' ? 0x40 : 0) |+        (Bit5 == '1' ? 0x20 : 0) |+        (Bit4 == '1' ? 0x10 : 0) |+        (Bit3 == '1' ? 0x08 : 0) |+        (Bit2 == '1' ? 0x04 : 0) |+        (Bit1 == '1' ? 0x02 : 0) |+        (Bit0 == '1' ? 0x01 : 0))+    >, Chars...> {};++template <unsigned char... Bytes, char... Chars>+struct bin_literal<bytes<Bytes...>, Chars...>+{+  static_assert(sizeof...(Chars) == 0,+      "number of digits in a binary buffer literal must be a multiple of 8");++  static const std::size_t size = 0;+  static const unsigned char data[1];+};++template <unsigned char... Bytes, char... Chars>+const unsigned char bin_literal<bytes<Bytes...>, Chars...>::data[1] = {};++// Literal processor that converts hexadecimal literals to an array of bytes.++template <typename Bytes, char... Chars>+struct hex_literal;++template <unsigned char... Bytes>+struct hex_literal<bytes<Bytes...> >+{+  static const std::size_t size = sizeof...(Bytes);+  static const unsigned char data[sizeof...(Bytes)];+};++template <unsigned char... Bytes>+const unsigned char hex_literal<bytes<Bytes...> >::data[sizeof...(Bytes)]+  = { Bytes... };++template <unsigned char... Bytes, char Hi, char Lo, char... Chars>+struct hex_literal<bytes<Bytes...>, Hi, Lo, Chars...> :+  hex_literal<+    bytes<Bytes...,+      static_cast<unsigned char>(+        Lo >= 'A' && Lo <= 'F' ? Lo - 'A' + 10 :+          (Lo >= 'a' && Lo <= 'f' ? Lo - 'a' + 10 : Lo - '0')) |+      ((static_cast<unsigned char>(+        Hi >= 'A' && Hi <= 'F' ? Hi - 'A' + 10 :+          (Hi >= 'a' && Hi <= 'f' ? Hi - 'a' + 10 : Hi - '0'))) << 4)+    >, Chars...> {};++template <unsigned char... Bytes, char Char>+struct hex_literal<bytes<Bytes...>, Char>+{+  static_assert(!Char,+      "a hexadecimal buffer literal must have an even number of digits");++  static const std::size_t size = 0;+  static const unsigned char data[1];+};++template <unsigned char... Bytes, char Char>+const unsigned char hex_literal<bytes<Bytes...>, Char>::data[1] = {};++// Helper template that removes digit separators and then passes the cleaned+// variadic pack of characters to the literal processor.++template <template <typename, char...> class Literal,+    typename Clean, char... Raw>+struct remove_separators;++template <template <typename, char...> class Literal,+    char... Clean, char... Raw>+struct remove_separators<Literal, chars<Clean...>, '\'', Raw...> :+  remove_separators<Literal, chars<Clean...>, Raw...> {};++template <template <typename, char...> class Literal,+    char... Clean, char C, char... Raw>+struct remove_separators<Literal, chars<Clean...>, C, Raw...> :+  remove_separators<Literal, chars<Clean..., C>, Raw...> {};++template <template <typename, char...> class Literal, char... Clean>+struct remove_separators<Literal, chars<Clean...> > :+  Literal<bytes<>, Clean...> {};++// Helper template to determine the literal type based on the prefix.++template <char... Chars>+struct literal;++template <char... Chars>+struct literal<'0', 'b', Chars...> :+  remove_separators<bin_literal, chars<>, Chars...>{};++template <char... Chars>+struct literal<'0', 'B', Chars...> :+  remove_separators<bin_literal, chars<>, Chars...>{};++template <char... Chars>+struct literal<'0', 'x', Chars...> :+  remove_separators<hex_literal, chars<>, Chars...>{};++template <char... Chars>+struct literal<'0', 'X', Chars...> :+  remove_separators<hex_literal, chars<>, Chars...>{};++} // namespace detail++/// Literal operator for creating const_buffer objects from string literals.+inline ASIO_CONST_BUFFER operator"" _buf(const char* data, std::size_t n)+{+  return ASIO_CONST_BUFFER(data, n);+}++/// Literal operator for creating const_buffer objects from unbounded binary or+/// hexadecimal integer literals.+template <char... Chars>+inline ASIO_CONST_BUFFER operator"" _buf()+{+  return ASIO_CONST_BUFFER(+      +detail::literal<Chars...>::data,+      detail::literal<Chars...>::size);+}++} // namespace buffer_literals++#endif // (defined(ASIO_HAS_USER_DEFINED_LITERALS)+       //     && defined(ASIO_HAS_VARIADIC_TEMPLATES))+       //   || defined(GENERATING_DOCUMENTATION)+ } // namespace asio  #include "asio/detail/pop_options.hpp"
link/modules/asio-standalone/asio/include/asio/buffer_registration.hpp view
@@ -2,7 +2,7 @@ // buffer_registration.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,7 +17,6 @@  #include "asio/detail/config.hpp" #include <iterator>-#include <utility> #include <vector> #include "asio/detail/memory.hpp" #include "asio/execution/context.hpp"@@ -32,6 +31,10 @@ # include "asio/detail/io_uring_service.hpp" #endif // defined(ASIO_HAS_IO_URING) +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -41,7 +44,7 @@ { protected:   static mutable_registered_buffer make_buffer(const mutable_buffer& b,-      const void* scope, int index) noexcept+      const void* scope, int index) ASIO_NOEXCEPT   {     return mutable_registered_buffer(b, registered_buffer_id(scope, index));   }@@ -55,7 +58,7 @@  * permitted per execution context.  */ template <typename MutableBufferSequence,-    typename Allocator = std::allocator<void>>+    typename Allocator = std::allocator<void> > class buffer_registration   : detail::buffer_registration_base {@@ -79,9 +82,9 @@   buffer_registration(const Executor& ex,       const MutableBufferSequence& buffer_sequence,       const allocator_type& alloc = allocator_type(),-      constraint_t<+      typename constraint<         is_executor<Executor>::value || execution::is_executor<Executor>::value-      > = 0)+      >::type = 0)     : buffer_sequence_(buffer_sequence),       buffers_(           ASIO_REBIND_ALLOC(allocator_type,@@ -97,9 +100,9 @@   buffer_registration(ExecutionContext& ctx,       const MutableBufferSequence& buffer_sequence,       const allocator_type& alloc = allocator_type(),-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : buffer_sequence_(buffer_sequence),       buffers_(           ASIO_REBIND_ALLOC(allocator_type,@@ -110,8 +113,9 @@         asio::buffer_sequence_end(buffer_sequence_));   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.-  buffer_registration(buffer_registration&& other) noexcept+  buffer_registration(buffer_registration&& other) ASIO_NOEXCEPT     : buffer_sequence_(std::move(other.buffer_sequence_)),       buffers_(std::move(other.buffers_))   {@@ -120,6 +124,7 @@     other.service_ = 0; #endif // defined(ASIO_HAS_IO_URING)   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Unregisters the buffers.   ~buffer_registration()@@ -129,9 +134,11 @@       service_->unregister_buffers(); #endif // defined(ASIO_HAS_IO_URING)   }-+  +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move assignment.-  buffer_registration& operator=(buffer_registration&& other) noexcept+  buffer_registration& operator=(+      buffer_registration&& other) ASIO_NOEXCEPT   {     if (this != &other)     {@@ -146,58 +153,59 @@     }     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Get the number of registered buffers.-  std::size_t size() const noexcept+  std::size_t size() const ASIO_NOEXCEPT   {     return buffers_.size();   }    /// Get the begin iterator for the sequence of registered buffers.-  const_iterator begin() const noexcept+  const_iterator begin() const ASIO_NOEXCEPT   {     return buffers_.begin();   }    /// Get the begin iterator for the sequence of registered buffers.-  const_iterator cbegin() const noexcept+  const_iterator cbegin() const ASIO_NOEXCEPT   {     return buffers_.cbegin();   }    /// Get the end iterator for the sequence of registered buffers.-  const_iterator end() const noexcept+  const_iterator end() const ASIO_NOEXCEPT   {     return buffers_.end();   }    /// Get the end iterator for the sequence of registered buffers.-  const_iterator cend() const noexcept+  const_iterator cend() const ASIO_NOEXCEPT   {     return buffers_.cend();   }    /// Get the buffer at the specified index.-  const mutable_registered_buffer& operator[](std::size_t i) noexcept+  const mutable_registered_buffer& operator[](std::size_t i) ASIO_NOEXCEPT   {     return buffers_[i];   }    /// Get the buffer at the specified index.-  const mutable_registered_buffer& at(std::size_t i) noexcept+  const mutable_registered_buffer& at(std::size_t i) ASIO_NOEXCEPT   {     return buffers_.at(i);   }  private:   // Disallow copying and assignment.-  buffer_registration(const buffer_registration&) = delete;-  buffer_registration& operator=(const buffer_registration&) = delete;+  buffer_registration(const buffer_registration&) ASIO_DELETED;+  buffer_registration& operator=(const buffer_registration&) ASIO_DELETED;    // Helper function to get an executor's context.   template <typename T>   static execution_context& get_context(const T& t,-      enable_if_t<execution::is_executor<T>::value>* = 0)+      typename enable_if<execution::is_executor<T>::value>::type* = 0)   {     return asio::query(t, execution::context);   }@@ -205,7 +213,7 @@   // Helper function to get an executor's context.   template <typename T>   static execution_context& get_context(const T& t,-      enable_if_t<!execution::is_executor<T>::value>* = 0)+      typename enable_if<!execution::is_executor<T>::value>::type* = 0)   {     return t.context();   }@@ -256,15 +264,16 @@ #endif // defined(ASIO_HAS_IO_URING) }; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Register buffers with an execution context. template <typename Executor, typename MutableBufferSequence> ASIO_NODISCARD inline buffer_registration<MutableBufferSequence> register_buffers(const Executor& ex,     const MutableBufferSequence& buffer_sequence,-    constraint_t<+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)+    >::type = 0) {   return buffer_registration<MutableBufferSequence>(ex, buffer_sequence); }@@ -275,9 +284,9 @@ buffer_registration<MutableBufferSequence, Allocator> register_buffers(const Executor& ex,     const MutableBufferSequence& buffer_sequence, const Allocator& alloc,-    constraint_t<+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)+    >::type = 0) {   return buffer_registration<MutableBufferSequence, Allocator>(       ex, buffer_sequence, alloc);@@ -289,9 +298,9 @@ buffer_registration<MutableBufferSequence> register_buffers(ExecutionContext& ctx,     const MutableBufferSequence& buffer_sequence,-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)+    >::type = 0) {   return buffer_registration<MutableBufferSequence>(ctx, buffer_sequence); }@@ -303,13 +312,14 @@ buffer_registration<MutableBufferSequence, Allocator> register_buffers(ExecutionContext& ctx,     const MutableBufferSequence& buffer_sequence, const Allocator& alloc,-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)+    >::type = 0) {   return buffer_registration<MutableBufferSequence, Allocator>(       ctx, buffer_sequence, alloc); }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/buffered_read_stream.hpp view
@@ -2,7 +2,7 @@ // buffered_read_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -55,7 +55,7 @@ { public:   /// The type of the next layer.-  typedef remove_reference_t<Stream> next_layer_type;+  typedef typename remove_reference<Stream>::type next_layer_type;    /// The type of the lowest layer.   typedef typename next_layer_type::lowest_layer_type lowest_layer_type;@@ -72,17 +72,17 @@    /// Construct, passing the specified argument to initialise the next layer.   template <typename Arg>-  explicit buffered_read_stream(Arg&& a)-    : next_layer_(static_cast<Arg&&>(a)),+  explicit buffered_read_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a)+    : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)),       storage_(default_buffer_size)   {   }    /// Construct, passing the specified argument to initialise the next layer.   template <typename Arg>-  buffered_read_stream(Arg&& a,+  buffered_read_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a,       std::size_t buffer_size)-    : next_layer_(static_cast<Arg&&>(a)),+    : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)),       storage_(buffer_size)   {   }@@ -106,7 +106,7 @@   }    /// Get the executor associated with the object.-  executor_type get_executor() noexcept+  executor_type get_executor() ASIO_NOEXCEPT   {     return next_layer_.lowest_layer().get_executor();   }@@ -149,15 +149,20 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteHandler = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(-      declval<conditional_t<true, Stream&, WriteHandler>>().async_write_some(-        buffers, static_cast<WriteHandler&&>(handler)))+        std::size_t)) WriteHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+      declval<typename conditional<true, Stream&, WriteHandler>::type>()+        .async_write_some(buffers,+          ASIO_MOVE_CAST(WriteHandler)(handler))))   {     return next_layer_.async_write_some(buffers,-        static_cast<WriteHandler&&>(handler));+        ASIO_MOVE_CAST(WriteHandler)(handler));   }    /// Fill the buffer with some data. Returns the number of bytes placed in the@@ -175,14 +180,18 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadHandler = default_completion_token_t<executor_type>>-  auto async_fill(-      ReadHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+      void (asio::error_code, std::size_t))+  async_fill(+      ASIO_MOVE_ARG(ReadHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadHandler,         void (asio::error_code, std::size_t)>(-          declval<detail::initiate_async_buffered_fill<Stream>>(),-          handler, declval<detail::buffered_stream_storage*>()));+          declval<detail::initiate_async_buffered_fill<Stream> >(),+          handler, declval<detail::buffered_stream_storage*>())));    /// Read some data from the stream. Returns the number of bytes read. Throws   /// an exception on failure.@@ -203,14 +212,18 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadHandler = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadHandler,         void (asio::error_code, std::size_t)>(-          declval<detail::initiate_async_buffered_read_some<Stream>>(),-          handler, declval<detail::buffered_stream_storage*>(), buffers));+          declval<detail::initiate_async_buffered_read_some<Stream> >(),+          handler, declval<detail::buffered_stream_storage*>(), buffers)));    /// Peek at the incoming data on the stream. Returns the number of bytes read.   /// Throws an exception on failure.
link/modules/asio-standalone/asio/include/asio/buffered_read_stream_fwd.hpp view
@@ -2,7 +2,7 @@ // buffered_read_stream_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/buffered_stream.hpp view
@@ -2,7 +2,7 @@ // buffered_stream.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -46,7 +46,7 @@ { public:   /// The type of the next layer.-  typedef remove_reference_t<Stream> next_layer_type;+  typedef typename remove_reference<Stream>::type next_layer_type;    /// The type of the lowest layer.   typedef typename next_layer_type::lowest_layer_type lowest_layer_type;@@ -56,17 +56,17 @@    /// Construct, passing the specified argument to initialise the next layer.   template <typename Arg>-  explicit buffered_stream(Arg&& a)-    : inner_stream_impl_(static_cast<Arg&&>(a)),+  explicit buffered_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a)+    : inner_stream_impl_(ASIO_MOVE_OR_LVALUE(Arg)(a)),       stream_impl_(inner_stream_impl_)   {   }    /// Construct, passing the specified argument to initialise the next layer.   template <typename Arg>-  explicit buffered_stream(Arg&& a,+  explicit buffered_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a,       std::size_t read_buffer_size, std::size_t write_buffer_size)-    : inner_stream_impl_(static_cast<Arg&&>(a), write_buffer_size),+    : inner_stream_impl_(ASIO_MOVE_OR_LVALUE(Arg)(a), write_buffer_size),       stream_impl_(inner_stream_impl_, read_buffer_size)   {   }@@ -90,7 +90,7 @@   }    /// Get the executor associated with the object.-  executor_type get_executor() noexcept+  executor_type get_executor() ASIO_NOEXCEPT   {     return stream_impl_.lowest_layer().get_executor();   }@@ -131,15 +131,19 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteHandler = default_completion_token_t<executor_type>>-  auto async_flush(-      WriteHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+      void (asio::error_code, std::size_t))+  async_flush(+      ASIO_MOVE_ARG(WriteHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       declval<buffered_write_stream<Stream>&>().async_flush(-        static_cast<WriteHandler&&>(handler)))+          ASIO_MOVE_CAST(WriteHandler)(handler))))   {     return stream_impl_.next_layer().async_flush(-        static_cast<WriteHandler&&>(handler));+        ASIO_MOVE_CAST(WriteHandler)(handler));   }    /// Write the given data to the stream. Returns the number of bytes written.@@ -167,15 +171,19 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteHandler = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       declval<Stream&>().async_write_some(buffers,-        static_cast<WriteHandler&&>(handler)))+          ASIO_MOVE_CAST(WriteHandler)(handler))))   {     return stream_impl_.async_write_some(buffers,-        static_cast<WriteHandler&&>(handler));+        ASIO_MOVE_CAST(WriteHandler)(handler));   }    /// Fill the buffer with some data. Returns the number of bytes placed in the@@ -199,15 +207,19 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadHandler = default_completion_token_t<executor_type>>-  auto async_fill(-      ReadHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+      void (asio::error_code, std::size_t))+  async_fill(+      ASIO_MOVE_ARG(ReadHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       declval<buffered_read_stream<-        buffered_write_stream<Stream>>&>().async_fill(-          static_cast<ReadHandler&&>(handler)))+        buffered_write_stream<Stream> >&>().async_fill(+          ASIO_MOVE_CAST(ReadHandler)(handler))))   {-    return stream_impl_.async_fill(static_cast<ReadHandler&&>(handler));+    return stream_impl_.async_fill(ASIO_MOVE_CAST(ReadHandler)(handler));   }    /// Read some data from the stream. Returns the number of bytes read. Throws@@ -235,15 +247,19 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadHandler = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       declval<Stream&>().async_read_some(buffers,-        static_cast<ReadHandler&&>(handler)))+          ASIO_MOVE_CAST(ReadHandler)(handler))))   {     return stream_impl_.async_read_some(buffers,-        static_cast<ReadHandler&&>(handler));+        ASIO_MOVE_CAST(ReadHandler)(handler));   }    /// Peek at the incoming data on the stream. Returns the number of bytes read.
link/modules/asio-standalone/asio/include/asio/buffered_stream_fwd.hpp view
@@ -2,7 +2,7 @@ // buffered_stream_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/buffered_write_stream.hpp view
@@ -2,7 +2,7 @@ // buffered_write_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -55,7 +55,7 @@ { public:   /// The type of the next layer.-  typedef remove_reference_t<Stream> next_layer_type;+  typedef typename remove_reference<Stream>::type next_layer_type;    /// The type of the lowest layer.   typedef typename next_layer_type::lowest_layer_type lowest_layer_type;@@ -72,17 +72,17 @@    /// Construct, passing the specified argument to initialise the next layer.   template <typename Arg>-  explicit buffered_write_stream(Arg&& a)-    : next_layer_(static_cast<Arg&&>(a)),+  explicit buffered_write_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a)+    : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)),       storage_(default_buffer_size)   {   }    /// Construct, passing the specified argument to initialise the next layer.   template <typename Arg>-  buffered_write_stream(Arg&& a,+  buffered_write_stream(ASIO_MOVE_OR_LVALUE_ARG(Arg) a,       std::size_t buffer_size)-    : next_layer_(static_cast<Arg&&>(a)),+    : next_layer_(ASIO_MOVE_OR_LVALUE(Arg)(a)),       storage_(buffer_size)   {   }@@ -106,7 +106,7 @@   }    /// Get the executor associated with the object.-  executor_type get_executor() noexcept+  executor_type get_executor() ASIO_NOEXCEPT   {     return next_layer_.lowest_layer().get_executor();   }@@ -141,14 +141,18 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteHandler = default_completion_token_t<executor_type>>-  auto async_flush(-      WriteHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+      void (asio::error_code, std::size_t))+  async_flush(+      ASIO_MOVE_ARG(WriteHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteHandler,         void (asio::error_code, std::size_t)>(-          declval<detail::initiate_async_buffered_flush<Stream>>(),-          handler, declval<detail::buffered_stream_storage*>()));+          declval<detail::initiate_async_buffered_flush<Stream> >(),+          handler, declval<detail::buffered_stream_storage*>())));    /// Write the given data to the stream. Returns the number of bytes written.   /// Throws an exception on failure.@@ -169,14 +173,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteHandler = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteHandler,         void (asio::error_code, std::size_t)>(-          declval<detail::initiate_async_buffered_write_some<Stream>>(),-          handler, declval<detail::buffered_stream_storage*>(), buffers));+          declval<detail::initiate_async_buffered_write_some<Stream> >(),+          handler, declval<detail::buffered_stream_storage*>(), buffers)));    /// Read some data from the stream. Returns the number of bytes read. Throws   /// an exception on failure.@@ -203,15 +211,20 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadHandler = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadHandler&& handler = default_completion_token_t<executor_type>())-    -> decltype(-      declval<conditional_t<true, Stream&, ReadHandler>>().async_read_some(-        buffers, static_cast<ReadHandler&&>(handler)))+        std::size_t)) ReadHandler+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadHandler) handler+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+      declval<typename conditional<true, Stream&, ReadHandler>::type>()+        .async_read_some(buffers,+          ASIO_MOVE_CAST(ReadHandler)(handler))))   {     return next_layer_.async_read_some(buffers,-        static_cast<ReadHandler&&>(handler));+        ASIO_MOVE_CAST(ReadHandler)(handler));   }    /// Peek at the incoming data on the stream. Returns the number of bytes read.
link/modules/asio-standalone/asio/include/asio/buffered_write_stream_fwd.hpp view
@@ -2,7 +2,7 @@ // buffered_write_stream_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/buffers_iterator.hpp view
@@ -2,7 +2,7 @@ // buffers_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -38,7 +38,7 @@     template <typename ByteType>     struct byte_type     {-      typedef add_const_t<ByteType> type;+      typedef typename add_const<ByteType>::type type;     };   }; @@ -80,10 +80,30 @@   struct buffers_iterator_types<const_buffer, ByteType>   {     typedef const_buffer buffer_type;-    typedef add_const_t<ByteType> byte_type;+    typedef typename add_const<ByteType>::type byte_type;     typedef const const_buffer* const_iterator;   };-} // namespace detail++#if !defined(ASIO_NO_DEPRECATED)++  template <typename ByteType>+  struct buffers_iterator_types<mutable_buffers_1, ByteType>+  {+    typedef mutable_buffer buffer_type;+    typedef ByteType byte_type;+    typedef const mutable_buffer* const_iterator;+  };++  template <typename ByteType>+  struct buffers_iterator_types<const_buffers_1, ByteType>+  {+    typedef const_buffer buffer_type;+    typedef typename add_const<ByteType>::type byte_type;+    typedef const const_buffer* const_iterator;+  };++#endif // !defined(ASIO_NO_DEPRECATED)+}  /// A random access iterator over the bytes in a buffer sequence. template <typename BufferSequence, typename ByteType = char>
− link/modules/asio-standalone/asio/include/asio/cancel_after.hpp
@@ -1,301 +0,0 @@-//-// cancel_after.hpp-// ~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_CANCEL_AFTER_HPP-#define ASIO_CANCEL_AFTER_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/basic_waitable_timer.hpp"-#include "asio/cancellation_type.hpp"-#include "asio/detail/chrono.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/wait_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--/// A @ref completion_token adapter that cancels an operation after a timeout.-/**- * The cancel_after_t class is used to indicate that an asynchronous operation- * should be cancelled if not complete before the specified duration has- * elapsed.- */-template <typename CompletionToken, typename Clock,-    typename WaitTraits = asio::wait_traits<Clock>>-class cancel_after_t-{-public:-  /// Constructor.-  template <typename T>-  cancel_after_t(T&& completion_token, const typename Clock::duration& timeout,-      cancellation_type_t cancel_type = cancellation_type::terminal)-    : token_(static_cast<T&&>(completion_token)),-      timeout_(timeout),-      cancel_type_(cancel_type)-  {-  }--//private:-  CompletionToken token_;-  typename Clock::duration timeout_;-  cancellation_type_t cancel_type_;-};--/// A @ref completion_token adapter that cancels an operation after a timeout.-/**- * The cancel_after_timer class is used to indicate that an asynchronous- * operation should be cancelled if not complete before the specified duration- * has elapsed.- */-template <typename CompletionToken, typename Clock,-    typename WaitTraits = asio::wait_traits<Clock>,-    typename Executor = any_io_executor>-class cancel_after_timer-{-public:-  /// Constructor.-  template <typename T>-  cancel_after_timer(T&& completion_token,-      basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-      const typename Clock::duration& timeout,-      cancellation_type_t cancel_type = cancellation_type::terminal)-    : token_(static_cast<T&&>(completion_token)),-      timer_(timer),-      timeout_(timeout),-      cancel_type_(cancel_type)-  {-  }--//private:-  CompletionToken token_;-  basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;-  typename Clock::duration timeout_;-  cancellation_type_t cancel_type_;-};--/// A function object type that adapts a @ref completion_token to cancel an-/// operation after a timeout.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>>-class partial_cancel_after-{-public:-  /// Constructor that specifies the timeout duration and cancellation type.-  explicit partial_cancel_after(const typename Clock::duration& timeout,-      cancellation_type_t cancel_type = cancellation_type::terminal)-    : timeout_(timeout),-      cancel_type_(cancel_type)-  {-  }--  /// Adapt a @ref completion_token to specify that the completion handler-  /// arguments should be combined into a single tuple argument.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  cancel_after_t<decay_t<CompletionToken>, Clock, WaitTraits>-  operator()(CompletionToken&& completion_token) const-  {-    return cancel_after_t<decay_t<CompletionToken>, Clock, WaitTraits>(-        static_cast<CompletionToken&&>(completion_token),-        timeout_, cancel_type_);-  }--//private:-  typename Clock::duration timeout_;-  cancellation_type_t cancel_type_;-};--/// A function object type that adapts a @ref completion_token to cancel an-/// operation after a timeout.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>,-    typename Executor = any_io_executor>-class partial_cancel_after_timer-{-public:-  /// Constructor that specifies the timeout duration and cancellation type.-  explicit partial_cancel_after_timer(-      basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-      const typename Clock::duration& timeout,-      cancellation_type_t cancel_type = cancellation_type::terminal)-    : timer_(timer),-      timeout_(timeout),-      cancel_type_(cancel_type)-  {-  }--  /// Adapt a @ref completion_token to specify that the completion handler-  /// arguments should be combined into a single tuple argument.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  cancel_after_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>-  operator()(CompletionToken&& completion_token) const-  {-    return cancel_after_timer<decay_t<CompletionToken>,-      Clock, WaitTraits, Executor>(-        static_cast<CompletionToken&&>(completion_token),-        timeout_, cancel_type_);-  }--//private:-  basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;-  typename Clock::duration timeout_;-  cancellation_type_t cancel_type_;-};--/// Create a partial completion token adapter that cancels an operation if not-/// complete before the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Rep, typename Period>-ASIO_NODISCARD inline partial_cancel_after<chrono::steady_clock>-cancel_after(const chrono::duration<Rep, Period>& timeout,-    cancellation_type_t cancel_type = cancellation_type::terminal)-{-  return partial_cancel_after<chrono::steady_clock>(timeout, cancel_type);-}--/// Create a partial completion token adapter that cancels an operation if not-/// complete before the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename WaitTraits,-    typename Executor, typename Rep, typename Period>-ASIO_NODISCARD inline-partial_cancel_after_timer<Clock, WaitTraits, Executor>-cancel_after(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-    const chrono::duration<Rep, Period>& timeout,-    cancellation_type_t cancel_type = cancellation_type::terminal)-{-  return partial_cancel_after_timer<Clock, WaitTraits, Executor>(-      timer, timeout, cancel_type);-}--/// Adapt a @ref completion_token to cancel an operation if not complete before-/// the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Rep, typename Period, typename CompletionToken>-ASIO_NODISCARD inline-cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>-cancel_after(const chrono::duration<Rep, Period>& timeout,-    CompletionToken&& completion_token)-{-  return cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>(-      static_cast<CompletionToken&&>(completion_token),-      timeout, cancellation_type::terminal);-}--/// Adapt a @ref completion_token to cancel an operation if not complete before-/// the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Rep, typename Period, typename CompletionToken>-ASIO_NODISCARD inline-cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>-cancel_after(const chrono::duration<Rep, Period>& timeout,-    cancellation_type_t cancel_type, CompletionToken&& completion_token)-{-  return cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>(-      static_cast<CompletionToken&&>(completion_token), timeout, cancel_type);-}--/// Adapt a @ref completion_token to cancel an operation if not complete before-/// the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename WaitTraits, typename Executor,-    typename Rep, typename Period, typename CompletionToken>-ASIO_NODISCARD inline-cancel_after_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>-cancel_after(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-    const chrono::duration<Rep, Period>& timeout,-    CompletionToken&& completion_token)-{-  return cancel_after_timer<decay_t<CompletionToken>,-    Clock, WaitTraits, Executor>(-      static_cast<CompletionToken&&>(completion_token),-      timer, timeout, cancellation_type::terminal);-}--/// Adapt a @ref completion_token to cancel an operation if not complete before-/// the specified relative timeout has elapsed.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_after, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename WaitTraits, typename Executor,-    typename Rep, typename Period, typename CompletionToken>-ASIO_NODISCARD inline-cancel_after_timer<decay_t<CompletionToken>, chrono::steady_clock>-cancel_after(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-    const chrono::duration<Rep, Period>& timeout,-    cancellation_type_t cancel_type, CompletionToken&& completion_token)-{-  return cancel_after_timer<decay_t<CompletionToken>,-    Clock, WaitTraits, Executor>(-      static_cast<CompletionToken&&>(completion_token),-      timer, timeout, cancel_type);-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/impl/cancel_after.hpp"--#endif // ASIO_CANCEL_AFTER_HPP
− link/modules/asio-standalone/asio/include/asio/cancel_at.hpp
@@ -1,294 +0,0 @@-//-// cancel_at.hpp-// ~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_CANCEL_AT_HPP-#define ASIO_CANCEL_AT_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/basic_waitable_timer.hpp"-#include "asio/cancellation_type.hpp"-#include "asio/detail/chrono.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/wait_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--/// A @ref completion_token adapter that cancels an operation at a given time.-/**- * The cancel_at_t class is used to indicate that an asynchronous operation- * should be cancelled if not complete at the specified absolute time.- */-template <typename CompletionToken, typename Clock,-    typename WaitTraits = asio::wait_traits<Clock>>-class cancel_at_t-{-public:-  /// Constructor.-  template <typename T>-  cancel_at_t(T&& completion_token, const typename Clock::time_point& expiry,-      cancellation_type_t cancel_type = cancellation_type::terminal)-    : token_(static_cast<T&&>(completion_token)),-      expiry_(expiry),-      cancel_type_(cancel_type)-  {-  }--//private:-  CompletionToken token_;-  typename Clock::time_point expiry_;-  cancellation_type_t cancel_type_;-};--/// A @ref completion_token adapter that cancels an operation at a given time.-/**- * The cancel_at_timer class is used to indicate that an asynchronous operation- * should be cancelled if not complete at the specified absolute time.- */-template <typename CompletionToken, typename Clock,-    typename WaitTraits = asio::wait_traits<Clock>,-    typename Executor = any_io_executor>-class cancel_at_timer-{-public:-  /// Constructor.-  template <typename T>-  cancel_at_timer(T&& completion_token,-      basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-      const typename Clock::time_point& expiry,-      cancellation_type_t cancel_type = cancellation_type::terminal)-    : token_(static_cast<T&&>(completion_token)),-      timer_(timer),-      expiry_(expiry),-      cancel_type_(cancel_type)-  {-  }--//private:-  CompletionToken token_;-  basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;-  typename Clock::time_point expiry_;-  cancellation_type_t cancel_type_;-};--/// A function object type that adapts a @ref completion_token to cancel an-/// operation at a given time.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>>-class partial_cancel_at-{-public:-  /// Constructor that specifies the expiry and cancellation type.-  explicit partial_cancel_at(const typename Clock::time_point& expiry,-      cancellation_type_t cancel_type = cancellation_type::terminal)-    : expiry_(expiry),-      cancel_type_(cancel_type)-  {-  }--  /// Adapt a @ref completion_token to specify that the completion handler-  /// arguments should be combined into a single tuple argument.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  constexpr cancel_at_t<decay_t<CompletionToken>, Clock, WaitTraits>-  operator()(CompletionToken&& completion_token) const-  {-    return cancel_at_t<decay_t<CompletionToken>, Clock, WaitTraits>(-        static_cast<CompletionToken&&>(completion_token),-        expiry_, cancel_type_);-  }--//private:-  typename Clock::time_point expiry_;-  cancellation_type_t cancel_type_;-};--/// A function object type that adapts a @ref completion_token to cancel an-/// operation at a given time.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>,-    typename Executor = any_io_executor>-class partial_cancel_at_timer-{-public:-  /// Constructor that specifies the expiry and cancellation type.-  explicit partial_cancel_at_timer(-      basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-      const typename Clock::time_point& expiry,-      cancellation_type_t cancel_type = cancellation_type::terminal)-    : timer_(timer),-      expiry_(expiry),-      cancel_type_(cancel_type)-  {-  }--  /// Adapt a @ref completion_token to specify that the completion handler-  /// arguments should be combined into a single tuple argument.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>-  operator()(CompletionToken&& completion_token) const-  {-    return cancel_at_timer<decay_t<CompletionToken>,-      Clock, WaitTraits, Executor>(-        static_cast<CompletionToken&&>(completion_token),-        timer_, expiry_, cancel_type_);-  }--//private:-  basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;-  typename Clock::time_point expiry_;-  cancellation_type_t cancel_type_;-};--/// Create a partial completion token adapter that cancels an operation if not-/// complete by the specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename Duration>-ASIO_NODISCARD inline partial_cancel_at<Clock>-cancel_at(const chrono::time_point<Clock, Duration>& expiry,-    cancellation_type_t cancel_type = cancellation_type::terminal)-{-  return partial_cancel_at<Clock>(expiry, cancel_type);-}--/// Create a partial completion token adapter that cancels an operation if not-/// complete by the specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename Clock, typename WaitTraits,-    typename Executor, typename Duration>-ASIO_NODISCARD inline partial_cancel_at_timer<Clock, WaitTraits, Executor>-cancel_at(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-    const chrono::time_point<Clock, Duration>& expiry,-    cancellation_type_t cancel_type = cancellation_type::terminal)-{-  return partial_cancel_at_timer<Clock, WaitTraits, Executor>(-      timer, expiry, cancel_type);-}--/// Adapt a @ref completion_token to cancel an operation if not complete by the-/// specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename CompletionToken, typename Clock, typename Duration>-ASIO_NODISCARD inline cancel_at_t<decay_t<CompletionToken>, Clock>-cancel_at(const chrono::time_point<Clock, Duration>& expiry,-    CompletionToken&& completion_token)-{-  return cancel_at_t<decay_t<CompletionToken>, Clock>(-      static_cast<CompletionToken&&>(completion_token),-      expiry, cancellation_type::terminal);-}--/// Adapt a @ref completion_token to cancel an operation if not complete by the-/// specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename CompletionToken, typename Clock, typename Duration>-ASIO_NODISCARD inline cancel_at_t<decay_t<CompletionToken>, Clock>-cancel_at(const chrono::time_point<Clock, Duration>& expiry,-    cancellation_type_t cancel_type, CompletionToken&& completion_token)-{-  return cancel_at_t<decay_t<CompletionToken>, Clock>(-      static_cast<CompletionToken&&>(completion_token), expiry, cancel_type);-}--/// Adapt a @ref completion_token to cancel an operation if not complete by the-/// specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename CompletionToken, typename Clock,-    typename WaitTraits, typename Executor, typename Duration>-ASIO_NODISCARD inline-cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>-cancel_at(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-    const chrono::time_point<Clock, Duration>& expiry,-    CompletionToken&& completion_token)-{-  return cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>(-      static_cast<CompletionToken&&>(completion_token),-      timer, expiry, cancellation_type::terminal);-}--/// Adapt a @ref completion_token to cancel an operation if not complete by the-/// specified absolute time.-/**- * @par Thread Safety- * When an asynchronous operation is used with cancel_at, a timer async_wait- * operation is performed in parallel to the main operation. If this parallel- * async_wait completes first, a cancellation request is emitted to cancel the- * main operation. Consequently, the application must ensure that the- * asynchronous operation is performed within an implicit or explicit strand.- */-template <typename CompletionToken, typename Clock,-    typename WaitTraits, typename Executor, typename Duration>-ASIO_NODISCARD inline-cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>-cancel_at(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,-    const chrono::time_point<Clock, Duration>& expiry,-    cancellation_type_t cancel_type, CompletionToken&& completion_token)-{-  return cancel_at_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>(-      static_cast<CompletionToken&&>(completion_token),-      timer, expiry, cancel_type);-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/impl/cancel_at.hpp"--#endif // ASIO_CANCEL_AT_HPP
link/modules/asio-standalone/asio/include/asio/cancellation_signal.hpp view
@@ -2,7 +2,7 @@ // cancellation_signal.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/cancellation_type.hpp" #include "asio/detail/cstddef.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp" @@ -32,7 +33,7 @@ { public:   virtual void call(cancellation_type_t) = 0;-  virtual std::pair<void*, std::size_t> destroy() noexcept = 0;+  virtual std::pair<void*, std::size_t> destroy() ASIO_NOEXCEPT = 0;  protected:   ~cancellation_handler_base() {}@@ -43,26 +44,45 @@   : public cancellation_handler_base { public:+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)   template <typename... Args>-  cancellation_handler(std::size_t size, Args&&... args)-    : handler_(static_cast<Args&&>(args)...),+  cancellation_handler(std::size_t size, ASIO_MOVE_ARG(Args)... args)+    : handler_(ASIO_MOVE_CAST(Args)(args)...),       size_(size)   {   }+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+  cancellation_handler(std::size_t size)+    : handler_(),+      size_(size)+  {+  } +#define ASIO_PRIVATE_HANDLER_CTOR_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  cancellation_handler(std::size_t size, ASIO_VARIADIC_MOVE_PARAMS(n)) \+    : handler_(ASIO_VARIADIC_MOVE_ARGS(n)), \+      size_(size) \+  { \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_HANDLER_CTOR_DEF)+#undef ASIO_PRIVATE_HANDLER_CTOR_DEF+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+   void call(cancellation_type_t type)   {     handler_(type);   } -  std::pair<void*, std::size_t> destroy() noexcept+  std::pair<void*, std::size_t> destroy() ASIO_NOEXCEPT   {     std::pair<void*, std::size_t> mem(this, size_);     this->cancellation_handler::~cancellation_handler();     return mem;   } -  Handler& handler() noexcept+  Handler& handler() ASIO_NOEXCEPT   {     return handler_;   }@@ -84,7 +104,7 @@ class cancellation_signal { public:-  constexpr cancellation_signal()+  ASIO_CONSTEXPR cancellation_signal()     : handler_(0)   {   }@@ -103,11 +123,11 @@    * The signal object must remain valid for as long the slot may be used.    * Destruction of the signal invalidates the slot.    */-  cancellation_slot slot() noexcept;+  cancellation_slot slot() ASIO_NOEXCEPT;  private:-  cancellation_signal(const cancellation_signal&) = delete;-  cancellation_signal& operator=(const cancellation_signal&) = delete;+  cancellation_signal(const cancellation_signal&) ASIO_DELETED;+  cancellation_signal& operator=(const cancellation_signal&) ASIO_DELETED;    detail::cancellation_handler_base* handler_; };@@ -117,11 +137,13 @@ { public:   /// Creates a slot that is not connected to any cancellation signal.-  constexpr cancellation_slot()+  ASIO_CONSTEXPR cancellation_slot()     : handler_(0)   {   } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)   /// Installs a handler into the slot, constructing the new object directly.   /**    * Destroys any existing handler in the slot, then installs the new handler,@@ -140,21 +162,58 @@    * be copy constructible or move constructible.    */   template <typename CancellationHandler, typename... Args>-  CancellationHandler& emplace(Args&&... args)+  CancellationHandler& emplace(ASIO_MOVE_ARG(Args)... args)   {     typedef detail::cancellation_handler<CancellationHandler>       cancellation_handler_type;     auto_delete_helper del = { prepare_memory(         sizeof(cancellation_handler_type),-        alignof(CancellationHandler)) };+        ASIO_ALIGNOF(CancellationHandler)) };     cancellation_handler_type* handler_obj =       new (del.mem.first) cancellation_handler_type(-        del.mem.second, static_cast<Args&&>(args)...);+        del.mem.second, ASIO_MOVE_CAST(Args)(args)...);     del.mem.first = 0;     *handler_ = handler_obj;     return handler_obj->handler();   }+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+      //   || defined(GENERATING_DOCUMENTATION)+  template <typename CancellationHandler>+  CancellationHandler& emplace()+  {+    typedef detail::cancellation_handler<CancellationHandler>+      cancellation_handler_type;+    auto_delete_helper del = { prepare_memory(+        sizeof(cancellation_handler_type),+        ASIO_ALIGNOF(CancellationHandler)) };+    cancellation_handler_type* handler_obj =+      new (del.mem.first) cancellation_handler_type(del.mem.second);+    del.mem.first = 0;+    *handler_ = handler_obj;+    return handler_obj->handler();+  } +#define ASIO_PRIVATE_HANDLER_EMPLACE_DEF(n) \+  template <typename CancellationHandler, ASIO_VARIADIC_TPARAMS(n)> \+  CancellationHandler& emplace(ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    typedef detail::cancellation_handler<CancellationHandler> \+      cancellation_handler_type; \+    auto_delete_helper del = { prepare_memory( \+        sizeof(cancellation_handler_type), \+        ASIO_ALIGNOF(CancellationHandler)) }; \+    cancellation_handler_type* handler_obj = \+      new (del.mem.first) cancellation_handler_type( \+        del.mem.second, ASIO_VARIADIC_MOVE_ARGS(n)); \+    del.mem.first = 0; \+    *handler_ = handler_obj; \+    return handler_obj->handler(); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_HANDLER_EMPLACE_DEF)+#undef ASIO_PRIVATE_HANDLER_EMPLACE_DEF+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+   /// Installs a handler into the slot.   /**    * Destroys any existing handler in the slot, then installs the new handler,@@ -169,10 +228,11 @@    * @returns A reference to the newly installed handler.    */   template <typename CancellationHandler>-  decay_t<CancellationHandler>& assign(CancellationHandler&& handler)+  typename decay<CancellationHandler>::type& assign(+      ASIO_MOVE_ARG(CancellationHandler) handler)   {-    return this->emplace<decay_t<CancellationHandler>>(-        static_cast<CancellationHandler&&>(handler));+    return this->emplace<typename decay<CancellationHandler>::type>(+        ASIO_MOVE_CAST(CancellationHandler)(handler));   }    /// Clears the slot.@@ -182,27 +242,27 @@   ASIO_DECL void clear();    /// Returns whether the slot is connected to a signal.-  constexpr bool is_connected() const noexcept+  ASIO_CONSTEXPR bool is_connected() const ASIO_NOEXCEPT   {     return handler_ != 0;   }    /// Returns whether the slot is connected and has an installed handler.-  constexpr bool has_handler() const noexcept+  ASIO_CONSTEXPR bool has_handler() const ASIO_NOEXCEPT   {     return handler_ != 0 && *handler_ != 0;   }    /// Compare two slots for equality.-  friend constexpr bool operator==(const cancellation_slot& lhs,-      const cancellation_slot& rhs) noexcept+  friend ASIO_CONSTEXPR bool operator==(const cancellation_slot& lhs,+      const cancellation_slot& rhs) ASIO_NOEXCEPT   {     return lhs.handler_ == rhs.handler_;   }    /// Compare two slots for inequality.-  friend constexpr bool operator!=(const cancellation_slot& lhs,-      const cancellation_slot& rhs) noexcept+  friend ASIO_CONSTEXPR bool operator!=(const cancellation_slot& lhs,+      const cancellation_slot& rhs) ASIO_NOEXCEPT   {     return lhs.handler_ != rhs.handler_;   }@@ -210,7 +270,7 @@ private:   friend class cancellation_signal; -  constexpr cancellation_slot(int,+  ASIO_CONSTEXPR cancellation_slot(int,       detail::cancellation_handler_base** handler)     : handler_(handler)   {@@ -229,7 +289,7 @@   detail::cancellation_handler_base** handler_; }; -inline cancellation_slot cancellation_signal::slot() noexcept+inline cancellation_slot cancellation_signal::slot() ASIO_NOEXCEPT {   return cancellation_slot(0, &handler_); }
link/modules/asio-standalone/asio/include/asio/cancellation_state.hpp view
@@ -2,7 +2,7 @@ // cancellation_state.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -32,7 +32,7 @@ {   /// Returns <tt>type & Mask</tt>.   cancellation_type_t operator()(-      cancellation_type_t type) const noexcept+      cancellation_type_t type) const ASIO_NOEXCEPT   {     return type & Mask;   }@@ -80,7 +80,7 @@ { public:   /// Construct a disconnected cancellation state.-  constexpr cancellation_state() noexcept+  ASIO_CONSTEXPR cancellation_state() ASIO_NOEXCEPT     : impl_(0)   {   }@@ -95,8 +95,8 @@    * attached.    */   template <typename CancellationSlot>-  constexpr explicit cancellation_state(CancellationSlot slot)-    : impl_(slot.is_connected() ? &slot.template emplace<impl<>>() : 0)+  ASIO_CONSTEXPR explicit cancellation_state(CancellationSlot slot)+    : impl_(slot.is_connected() ? &slot.template emplace<impl<> >() : 0)   {   } @@ -119,9 +119,9 @@    * @li asio::enable_total_cancellation    */   template <typename CancellationSlot, typename Filter>-  constexpr cancellation_state(CancellationSlot slot, Filter filter)+  ASIO_CONSTEXPR cancellation_state(CancellationSlot slot, Filter filter)     : impl_(slot.is_connected()-        ? &slot.template emplace<impl<Filter, Filter>>(filter, filter)+        ? &slot.template emplace<impl<Filter, Filter> >(filter, filter)         : 0)   {   }@@ -151,12 +151,12 @@    * @li asio::enable_total_cancellation    */   template <typename CancellationSlot, typename InFilter, typename OutFilter>-  constexpr cancellation_state(CancellationSlot slot,+  ASIO_CONSTEXPR cancellation_state(CancellationSlot slot,       InFilter in_filter, OutFilter out_filter)     : impl_(slot.is_connected()-        ? &slot.template emplace<impl<InFilter, OutFilter>>(-            static_cast<InFilter&&>(in_filter),-            static_cast<OutFilter&&>(out_filter))+        ? &slot.template emplace<impl<InFilter, OutFilter> >(+            ASIO_MOVE_CAST(InFilter)(in_filter),+            ASIO_MOVE_CAST(OutFilter)(out_filter))         : 0)   {   }@@ -165,20 +165,20 @@   /**    * This sub-slot is used with the operations that are being composed.    */-  constexpr cancellation_slot slot() const noexcept+  ASIO_CONSTEXPR cancellation_slot slot() const ASIO_NOEXCEPT   {     return impl_ ? impl_->signal_.slot() : cancellation_slot();   }    /// Returns the cancellation types that have been triggered.-  cancellation_type_t cancelled() const noexcept+  cancellation_type_t cancelled() const ASIO_NOEXCEPT   {     return impl_ ? impl_->cancelled_ : cancellation_type_t();   }    /// Clears the specified cancellation types, if they have been triggered.   void clear(cancellation_type_t mask = cancellation_type::all)-    noexcept+    ASIO_NOEXCEPT   {     if (impl_)       impl_->cancelled_ &= ~mask;@@ -208,8 +208,8 @@     }      impl(InFilter in_filter, OutFilter out_filter)-      : in_filter_(static_cast<InFilter&&>(in_filter)),-        out_filter_(static_cast<OutFilter&&>(out_filter))+      : in_filter_(ASIO_MOVE_CAST(InFilter)(in_filter)),+        out_filter_(ASIO_MOVE_CAST(OutFilter)(out_filter))     {     } 
link/modules/asio-standalone/asio/include/asio/cancellation_type.hpp view
@@ -2,7 +2,7 @@ // cancellation_type.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -51,7 +51,7 @@ /// Portability typedef. typedef cancellation_type cancellation_type_t; -#else // defined(GENERATING_DOCUMENTATION)+#elif defined(ASIO_HAS_ENUM_CLASS)  enum class cancellation_type : unsigned int {@@ -64,13 +64,30 @@  typedef cancellation_type cancellation_type_t; -#endif // defined(GENERATING_DOCUMENTATION)+#else // defined(ASIO_HAS_ENUM_CLASS) +namespace cancellation_type {++enum cancellation_type_t+{+  none = 0,+  terminal = 1,+  partial = 2,+  total = 4,+  all = 0xFFFFFFFF+};++} // namespace cancellation_type++typedef cancellation_type::cancellation_type_t cancellation_type_t;++#endif // defined(ASIO_HAS_ENUM_CLASS)+ /// Negation operator. /**  * @relates cancellation_type  */-inline constexpr bool operator!(cancellation_type_t x)+inline ASIO_CONSTEXPR bool operator!(cancellation_type_t x) {   return static_cast<unsigned int>(x) == 0; }@@ -79,7 +96,7 @@ /**  * @relates cancellation_type  */-inline constexpr cancellation_type_t operator&(+inline ASIO_CONSTEXPR cancellation_type_t operator&(     cancellation_type_t x, cancellation_type_t y) {   return static_cast<cancellation_type_t>(@@ -90,7 +107,7 @@ /**  * @relates cancellation_type  */-inline constexpr cancellation_type_t operator|(+inline ASIO_CONSTEXPR cancellation_type_t operator|(     cancellation_type_t x, cancellation_type_t y) {   return static_cast<cancellation_type_t>(@@ -101,7 +118,7 @@ /**  * @relates cancellation_type  */-inline constexpr cancellation_type_t operator^(+inline ASIO_CONSTEXPR cancellation_type_t operator^(     cancellation_type_t x, cancellation_type_t y) {   return static_cast<cancellation_type_t>(@@ -112,7 +129,7 @@ /**  * @relates cancellation_type  */-inline constexpr cancellation_type_t operator~(cancellation_type_t x)+inline ASIO_CONSTEXPR cancellation_type_t operator~(cancellation_type_t x) {   return static_cast<cancellation_type_t>(~static_cast<unsigned int>(x)); }
− link/modules/asio-standalone/asio/include/asio/co_composed.hpp
@@ -1,1319 +0,0 @@-//-// co_composed.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_CO_COMPOSED_HPP-#define ASIO_CO_COMPOSED_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"--#if defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)--#include <new>-#include <tuple>-#include <variant>-#include "asio/associated_cancellation_slot.hpp"-#include "asio/associator.hpp"-#include "asio/async_result.hpp"-#include "asio/cancellation_state.hpp"-#include "asio/detail/composed_work.hpp"-#include "asio/detail/recycling_allocator.hpp"-#include "asio/detail/throw_error.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/error.hpp"--#if defined(ASIO_HAS_STD_COROUTINE)-# include <coroutine>-#else // defined(ASIO_HAS_STD_COROUTINE)-# include <experimental/coroutine>-#endif // defined(ASIO_HAS_STD_COROUTINE)--#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)-#  include "asio/detail/source_location.hpp"-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--#if defined(ASIO_HAS_STD_COROUTINE)-using std::coroutine_handle;-using std::suspend_always;-using std::suspend_never;-#else // defined(ASIO_HAS_STD_COROUTINE)-using std::experimental::coroutine_handle;-using std::experimental::suspend_always;-using std::experimental::suspend_never;-#endif // defined(ASIO_HAS_STD_COROUTINE)--using asio::detail::composed_io_executors;-using asio::detail::composed_work;-using asio::detail::composed_work_guard;-using asio::detail::get_composed_io_executor;-using asio::detail::make_composed_io_executors;-using asio::detail::recycling_allocator;-using asio::detail::throw_error;--template <typename Executors, typename Handler, typename Return>-class co_composed_state;--template <typename Executors, typename Handler, typename Return>-class co_composed_handler_base;--template <typename Executors, typename Handler, typename Return>-class co_composed_promise;--template <ASIO_COMPLETION_SIGNATURE... Signatures>-class co_composed_returns-{-};--struct co_composed_on_suspend-{-  void (*fn_)(void*) = nullptr;-  void* arg_ = nullptr;-};--template <typename... T>-struct co_composed_completion : std::tuple<T&&...>-{-  template <typename... U>-  co_composed_completion(U&&... u) noexcept-    : std::tuple<T&&...>(static_cast<U&&>(u)...)-  {-  }-};--template <typename Executors, typename Handler,-    typename Return, typename Signature>-class co_composed_state_return_overload;--template <typename Executors, typename Handler,-    typename Return, typename R, typename... Args>-class co_composed_state_return_overload<-    Executors, Handler, Return, R(Args...)>-{-public:-  using derived_type = co_composed_state<Executors, Handler, Return>;-  using promise_type = co_composed_promise<Executors, Handler, Return>;-  using return_type = std::tuple<Args...>;--  void on_cancellation_complete_with(Args... args)-  {-    derived_type& state = *static_cast<derived_type*>(this);-    state.return_value_ = std::make_tuple(std::move(args)...);-    state.cancellation_on_suspend_fn(-        [](void* p)-        {-          auto& promise = *static_cast<promise_type*>(p);--          co_composed_handler_base<Executors, Handler,-            Return> composed_handler(promise);--          Handler handler(std::move(promise.state().handler_));-          return_type result(-              std::move(std::get<return_type>(promise.state().return_value_)));--          co_composed_handler_base<Executors, Handler,-            Return>(std::move(composed_handler));--          std::apply(std::move(handler), std::move(result));-        });-  }-};--template <typename Executors, typename Handler, typename Return>-class co_composed_state_return;--template <typename Executors, typename Handler, typename... Signatures>-class co_composed_state_return<-    Executors, Handler, co_composed_returns<Signatures...>>-  : public co_composed_state_return_overload<Executors,-      Handler, co_composed_returns<Signatures...>, Signatures>...-{-public:-  using co_composed_state_return_overload<Executors,-    Handler, co_composed_returns<Signatures...>,-      Signatures>::on_cancellation_complete_with...;--private:-  template <typename, typename, typename, typename>-    friend class co_composed_promise_return_overload;-  template <typename, typename, typename, typename>-    friend class co_composed_state_return_overload;--  std::variant<std::monostate,-    typename co_composed_state_return_overload<-      Executors, Handler, co_composed_returns<Signatures...>,-        Signatures>::return_type...> return_value_;-};--template <typename Executors, typename Handler,-    typename Return, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend_impl;--template <typename Executors, typename Handler, typename Return>-struct co_composed_state_default_cancellation_on_suspend_impl<-    Executors, Handler, Return>-{-  static constexpr void (*fn())(void*)-  {-    return nullptr;-  }-};--template <typename Executors, typename Handler, typename Return,-    typename R, typename... Args, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend_impl<-    Executors, Handler, Return, R(Args...), Signatures...>-{-  static constexpr void (*fn())(void*)-  {-    return co_composed_state_default_cancellation_on_suspend_impl<-      Executors, Handler, Return, Signatures...>::fn();-  }-};--template <typename Executors, typename Handler, typename Return,-    typename R, typename... Args, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend_impl<Executors,-    Handler, Return, R(asio::error_code, Args...), Signatures...>-{-  using promise_type = co_composed_promise<Executors, Handler, Return>;-  using return_type = std::tuple<asio::error_code, Args...>;--  static constexpr void (*fn())(void*)-  {-    if constexpr ((is_constructible<Args>::value && ...))-    {-      return [](void* p)-      {-        auto& promise = *static_cast<promise_type*>(p);--        co_composed_handler_base<Executors, Handler,-          Return> composed_handler(promise);--        Handler handler(std::move(promise.state().handler_));--        co_composed_handler_base<Executors, Handler,-          Return>(std::move(composed_handler));--        std::move(handler)(-            asio::error_code(asio::error::operation_aborted),-            Args{}...);-      };-    }-    else-    {-      return co_composed_state_default_cancellation_on_suspend_impl<-        Executors, Handler, Return, Signatures...>::fn();-    }-  }-};--template <typename Executors, typename Handler, typename Return,-    typename R, typename... Args, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend_impl<Executors,-    Handler, Return, R(std::exception_ptr, Args...), Signatures...>-{-  using promise_type = co_composed_promise<Executors, Handler, Return>;-  using return_type = std::tuple<std::exception_ptr, Args...>;--  static constexpr void (*fn())(void*)-  {-    if constexpr ((is_constructible<Args>::value && ...))-    {-      return [](void* p)-      {-        auto& promise = *static_cast<promise_type*>(p);--        co_composed_handler_base<Executors, Handler,-          Return> composed_handler(promise);--        Handler handler(std::move(promise.state().handler_));--        co_composed_handler_base<Executors, Handler,-          Return>(std::move(composed_handler));--        std::move(handler)(-            std::make_exception_ptr(-              asio::system_error(-                asio::error::operation_aborted, "co_await")),-            Args{}...);-      };-    }-    else-    {-      return co_composed_state_default_cancellation_on_suspend_impl<-        Executors, Handler, Return, Signatures...>::fn();-    }-  }-};--template <typename Executors, typename Handler, typename Return>-struct co_composed_state_default_cancellation_on_suspend;--template <typename Executors, typename Handler, typename... Signatures>-struct co_composed_state_default_cancellation_on_suspend<-    Executors, Handler, co_composed_returns<Signatures...>>-  : co_composed_state_default_cancellation_on_suspend_impl<Executors,-      Handler, co_composed_returns<Signatures...>, Signatures...>-{-};--template <typename Executors, typename Handler, typename Return>-class co_composed_state_cancellation-{-public:-  using cancellation_slot_type = cancellation_slot;--  cancellation_slot_type get_cancellation_slot() const noexcept-  {-    return cancellation_state_.slot();-  }--  cancellation_state get_cancellation_state() const noexcept-  {-    return cancellation_state_;-  }--  void reset_cancellation_state()-  {-    cancellation_state_ = cancellation_state(-        (get_associated_cancellation_slot)(-          static_cast<co_composed_state<Executors, Handler, Return>*>(-            this)->handler()));-  }--  template <typename Filter>-  void reset_cancellation_state(Filter filter)-  {-    cancellation_state_ = cancellation_state(-        (get_associated_cancellation_slot)(-          static_cast<co_composed_state<Executors, Handler, Return>*>(-            this)->handler()), filter, filter);-  }--  template <typename InFilter, typename OutFilter>-  void reset_cancellation_state(InFilter&& in_filter, OutFilter&& out_filter)-  {-    cancellation_state_ = cancellation_state(-        (get_associated_cancellation_slot)(-          static_cast<co_composed_state<Executors, Handler, Return>*>(-            this)->handler()),-        static_cast<InFilter&&>(in_filter),-        static_cast<OutFilter&&>(out_filter));-  }--  cancellation_type_t cancelled() const noexcept-  {-    return cancellation_state_.cancelled();-  }--  void clear_cancellation_slot() noexcept-  {-    cancellation_state_.slot().clear();-  }--  [[nodiscard]] bool throw_if_cancelled() const noexcept-  {-    return throw_if_cancelled_;-  }--  void throw_if_cancelled(bool b) noexcept-  {-    throw_if_cancelled_ = b;-  }--  [[nodiscard]] bool complete_if_cancelled() const noexcept-  {-    return complete_if_cancelled_;-  }--  void complete_if_cancelled(bool b) noexcept-  {-    complete_if_cancelled_ = b;-  }--private:-  template <typename, typename, typename>-    friend class co_composed_promise;-  template <typename, typename, typename, typename>-    friend class co_composed_state_return_overload;--  void cancellation_on_suspend_fn(void (*fn)(void*))-  {-    cancellation_on_suspend_fn_ = fn;-  }--  void check_for_cancellation_on_transform()-  {-    if (throw_if_cancelled_ && !!cancelled())-      throw_error(asio::error::operation_aborted, "co_await");-  }--  bool check_for_cancellation_on_suspend(-      co_composed_promise<Executors, Handler, Return>& promise) noexcept-  {-    if (complete_if_cancelled_ && !!cancelled() && cancellation_on_suspend_fn_)-    {-      promise.state().work_.reset();-      promise.state().on_suspend_->fn_ = cancellation_on_suspend_fn_;-      promise.state().on_suspend_->arg_ = &promise;-      return false;-    }-    return true;-  }--  cancellation_state cancellation_state_;-  void (*cancellation_on_suspend_fn_)(void*) =-    co_composed_state_default_cancellation_on_suspend<-      Executors, Handler, Return>::fn();-  bool throw_if_cancelled_ = false;-  bool complete_if_cancelled_ = true;-};--template <typename Executors, typename Handler, typename Return>-  requires is_same<-    typename associated_cancellation_slot<-      Handler, cancellation_slot-    >::asio_associated_cancellation_slot_is_unspecialised,-    void>::value-class co_composed_state_cancellation<Executors, Handler, Return>-{-public:-  void reset_cancellation_state()-  {-  }--  template <typename Filter>-  void reset_cancellation_state(Filter)-  {-  }--  template <typename InFilter, typename OutFilter>-  void reset_cancellation_state(InFilter&&, OutFilter&&)-  {-  }--  cancellation_type_t cancelled() const noexcept-  {-    return cancellation_type::none;-  }--  void clear_cancellation_slot() noexcept-  {-  }--  [[nodiscard]] bool throw_if_cancelled() const noexcept-  {-    return false;-  }--  void throw_if_cancelled(bool) noexcept-  {-  }--  [[nodiscard]] bool complete_if_cancelled() const noexcept-  {-    return false;-  }--  void complete_if_cancelled(bool) noexcept-  {-  }--private:-  template <typename, typename, typename>-    friend class co_composed_promise;-  template <typename, typename, typename, typename>-    friend class co_composed_state_return_overload;--  void cancellation_on_suspend_fn(void (*)(void*))-  {-  }--  void check_for_cancellation_on_transform() noexcept-  {-  }--  bool check_for_cancellation_on_suspend(-      co_composed_promise<Executors, Handler, Return>&) noexcept-  {-    return true;-  }-};--template <typename Executors, typename Handler, typename Return>-class co_composed_state-  : public co_composed_state_return<Executors, Handler, Return>,-    public co_composed_state_cancellation<Executors, Handler, Return>-{-public:-  using io_executor_type = typename composed_work_guard<-    typename composed_work<Executors>::head_type>::executor_type;--  template <typename H>-  co_composed_state(composed_io_executors<Executors>&& executors,-      H&& h, co_composed_on_suspend& on_suspend)-    : work_(std::move(executors)),-      handler_(static_cast<H&&>(h)),-      on_suspend_(&on_suspend)-  {-    this->reset_cancellation_state(enable_terminal_cancellation());-  }--  io_executor_type get_io_executor() const noexcept-  {-    return work_.head_.get_executor();-  }--  template <typename... Args>-  [[nodiscard]] co_composed_completion<Args...> complete(Args&&... args)-    requires requires { declval<Handler>()(static_cast<Args&&>(args)...); }-  {-    return co_composed_completion<Args...>(static_cast<Args&&>(args)...);-  }--  const Handler& handler() const noexcept-  {-    return handler_;-  }--private:-  template <typename, typename, typename>-    friend class co_composed_handler_base;-  template <typename, typename, typename>-    friend class co_composed_promise;-  template <typename, typename, typename, typename>-    friend class co_composed_promise_return_overload;-  template <typename, typename, typename>-    friend class co_composed_state_cancellation;-  template <typename, typename, typename, typename>-    friend class co_composed_state_return_overload;-  template <typename, typename, typename, typename...>-    friend struct co_composed_state_default_cancellation_on_suspend_impl;--  composed_work<Executors> work_;-  Handler handler_;-  co_composed_on_suspend* on_suspend_;-};--template <typename Executors, typename Handler, typename Return>-class co_composed_handler_cancellation-{-public:-  using cancellation_slot_type = cancellation_slot;--  cancellation_slot_type get_cancellation_slot() const noexcept-  {-    return static_cast<-      const co_composed_handler_base<Executors, Handler, Return>*>(-        this)->promise().state().get_cancellation_slot();-  }-};--template <typename Executors, typename Handler, typename Return>-  requires is_same<-    typename associated_cancellation_slot<-      Handler, cancellation_slot-    >::asio_associated_cancellation_slot_is_unspecialised,-    void>::value-class co_composed_handler_cancellation<Executors, Handler, Return>-{-};--template <typename Executors, typename Handler, typename Return>-class co_composed_handler_base :-  public co_composed_handler_cancellation<Executors, Handler, Return>-{-public:-  co_composed_handler_base(-      co_composed_promise<Executors, Handler, Return>& p) noexcept-    : p_(&p)-  {-  }--  co_composed_handler_base(co_composed_handler_base&& other) noexcept-    : p_(std::exchange(other.p_, nullptr))-  {-  }--  ~co_composed_handler_base()-  {-    if (p_) [[unlikely]]-      p_->destroy();-  }--  co_composed_promise<Executors, Handler, Return>& promise() const noexcept-  {-    return *p_;-  }--protected:-  void resume(void* result)-  {-    co_composed_on_suspend on_suspend{};-    std::exchange(p_, nullptr)->resume(p_, result, on_suspend);-    if (on_suspend.fn_)-      on_suspend.fn_(on_suspend.arg_);-  }--private:-  co_composed_promise<Executors, Handler, Return>* p_;-};--template <typename Executors, typename Handler,-    typename Return, typename Signature>-class co_composed_handler;--template <typename Executors, typename Handler,-    typename Return, typename R, typename... Args>-class co_composed_handler<Executors, Handler, Return, R(Args...)>-  : public co_composed_handler_base<Executors, Handler, Return>-{-public:-  using co_composed_handler_base<Executors,-    Handler, Return>::co_composed_handler_base;--  using result_type = std::tuple<decay_t<Args>...>;--  template <typename... T>-  void operator()(T&&... args)-  {-    result_type result(static_cast<T&&>(args)...);-    this->resume(&result);-  }--  static auto on_resume(void* result)-  {-    auto& args = *static_cast<result_type*>(result);-    if constexpr (sizeof...(Args) == 0)-      return;-    else if constexpr (sizeof...(Args) == 1)-      return std::move(std::get<0>(args));-    else-      return std::move(args);-  }-};--template <typename Executors, typename Handler,-    typename Return, typename R, typename... Args>-class co_composed_handler<Executors, Handler,-    Return, R(asio::error_code, Args...)>-  : public co_composed_handler_base<Executors, Handler, Return>-{-public:-  using co_composed_handler_base<Executors,-    Handler, Return>::co_composed_handler_base;--  using args_type = std::tuple<decay_t<Args>...>;-  using result_type = std::tuple<asio::error_code, args_type>;--  template <typename... T>-  void operator()(const asio::error_code& ec, T&&... args)-  {-    result_type result(ec, args_type(static_cast<T&&>(args)...));-    this->resume(&result);-  }--  static auto on_resume(void* result)-  {-    auto& [ec, args] = *static_cast<result_type*>(result);-    throw_error(ec);-    if constexpr (sizeof...(Args) == 0)-      return;-    else if constexpr (sizeof...(Args) == 1)-      return std::move(std::get<0>(args));-    else-      return std::move(args);-  }-};--template <typename Executors, typename Handler,-    typename Return, typename R, typename... Args>-class co_composed_handler<Executors, Handler,-    Return, R(std::exception_ptr, Args...)>-  : public co_composed_handler_base<Executors, Handler, Return>-{-public:-  using co_composed_handler_base<Executors,-    Handler, Return>::co_composed_handler_base;--  using args_type = std::tuple<decay_t<Args>...>;-  using result_type = std::tuple<std::exception_ptr, args_type>;--  template <typename... T>-  void operator()(std::exception_ptr ex, T&&... args)-  {-    result_type result(std::move(ex), args_type(static_cast<T&&>(args)...));-    this->resume(&result);-  }--  static auto on_resume(void* result)-  {-    auto& [ex, args] = *static_cast<result_type*>(result);-    if (ex)-      std::rethrow_exception(ex);-    if constexpr (sizeof...(Args) == 0)-      return;-    else if constexpr (sizeof...(Args) == 1)-      return std::move(std::get<0>(args));-    else-      return std::move(args);-  }-};--template <typename Executors, typename Handler, typename Return>-class co_composed_promise_return;--template <typename Executors, typename Handler>-class co_composed_promise_return<Executors, Handler, co_composed_returns<>>-{-public:-  auto final_suspend() noexcept-  {-    return suspend_never();-  }--  void return_void() noexcept-  {-  }-};--template <typename Executors, typename Handler,-    typename Return, typename Signature>-class co_composed_promise_return_overload;--template <typename Executors, typename Handler,-    typename Return, typename R, typename... Args>-class co_composed_promise_return_overload<-    Executors, Handler, Return, R(Args...)>-{-public:-  using derived_type = co_composed_promise<Executors, Handler, Return>;-  using return_type = std::tuple<Args...>;--  void return_value(std::tuple<Args...>&& value)-  {-    derived_type& promise = *static_cast<derived_type*>(this);-    promise.state().return_value_ = std::move(value);-    promise.state().work_.reset();-    promise.state().on_suspend_->arg_ = this;-    promise.state().on_suspend_->fn_ =-      [](void* p)-      {-        auto& promise = *static_cast<derived_type*>(p);--        co_composed_handler_base<Executors, Handler,-          Return> composed_handler(promise);--        Handler handler(std::move(promise.state().handler_));-        return_type result(-            std::move(std::get<return_type>(promise.state().return_value_)));--        co_composed_handler_base<Executors, Handler,-          Return>(std::move(composed_handler));--        std::apply(std::move(handler), std::move(result));-      };-  }-};--template <typename Executors, typename Handler, typename... Signatures>-class co_composed_promise_return<Executors,-    Handler, co_composed_returns<Signatures...>>-  : public co_composed_promise_return_overload<Executors,-      Handler, co_composed_returns<Signatures...>, Signatures>...-{-public:-  auto final_suspend() noexcept-  {-    return suspend_always();-  }--  using co_composed_promise_return_overload<Executors, Handler,-    co_composed_returns<Signatures...>, Signatures>::return_value...;--private:-  template <typename, typename, typename, typename>-    friend class co_composed_promise_return_overload;-};--template <typename Executors, typename Handler, typename Return>-class co_composed_promise-  : public co_composed_promise_return<Executors, Handler, Return>-{-public:-  template <typename... Args>-  void* operator new(std::size_t size,-      co_composed_state<Executors, Handler, Return>& state, Args&&...)-  {-    block_allocator_type allocator(-      (get_associated_allocator)(state.handler_,-        recycling_allocator<void>()));--    block* base_ptr = std::allocator_traits<block_allocator_type>::allocate(-        allocator, blocks(sizeof(allocator_type)) + blocks(size));--    new (static_cast<void*>(base_ptr)) allocator_type(std::move(allocator));--    return base_ptr + blocks(sizeof(allocator_type));-  }--  template <typename C, typename... Args>-  void* operator new(std::size_t size, C&&,-      co_composed_state<Executors, Handler, Return>& state, Args&&...)-  {-    return co_composed_promise::operator new(size, state);-  }--  void operator delete(void* ptr, std::size_t size)-  {-    block* base_ptr = static_cast<block*>(ptr) - blocks(sizeof(allocator_type));--    allocator_type* allocator_ptr = std::launder(-        static_cast<allocator_type*>(static_cast<void*>(base_ptr)));--    block_allocator_type block_allocator(std::move(*allocator_ptr));-    allocator_ptr->~allocator_type();--    std::allocator_traits<block_allocator_type>::deallocate(block_allocator,-        base_ptr, blocks(sizeof(allocator_type)) + blocks(size));-  }--  template <typename... Args>-  co_composed_promise(-      co_composed_state<Executors, Handler, Return>& state, Args&&...)-    : state_(state)-  {-  }--  template <typename C, typename... Args>-  co_composed_promise(C&&,-      co_composed_state<Executors, Handler, Return>& state, Args&&...)-    : state_(state)-  {-  }--  void destroy() noexcept-  {-    coroutine_handle<co_composed_promise>::from_promise(*this).destroy();-  }--  void resume(co_composed_promise*& owner, void* result,-      co_composed_on_suspend& on_suspend)-  {-    state_.on_suspend_ = &on_suspend;-    state_.clear_cancellation_slot();-    owner_ = &owner;-    result_ = result;-    coroutine_handle<co_composed_promise>::from_promise(*this).resume();-  }--  co_composed_state<Executors, Handler, Return>& state() noexcept-  {-    return state_;-  }--  void get_return_object() noexcept-  {-  }--  auto initial_suspend() noexcept-  {-    return suspend_never();-  }--  void unhandled_exception()-  {-    if (owner_)-      *owner_ = this;-    throw;-  }--  template <ASIO_ASYNC_OPERATION Op>-  auto await_transform(Op&& op,-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)-      asio::detail::source_location location-        = asio::detail::source_location::current(),-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)-      constraint_t<is_async_operation<Op>::value> = 0)-  {-    class [[nodiscard]] awaitable-    {-    public:-      awaitable(Op&& op, co_composed_promise& promise-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)-          , const asio::detail::source_location& location-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)-        )-        : op_(static_cast<Op&&>(op)),-          promise_(promise)-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)-        , location_(location)-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)-      {-      }--      constexpr bool await_ready() const noexcept-      {-        return false;-      }--      void await_suspend(coroutine_handle<co_composed_promise>)-      {-        if (promise_.state_.check_for_cancellation_on_suspend(promise_))-        {-          promise_.state_.on_suspend_->arg_ = this;-          promise_.state_.on_suspend_->fn_ =-            [](void* p)-            {-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)-              ASIO_HANDLER_LOCATION((-                  static_cast<awaitable*>(p)->location_.file_name(),-                  static_cast<awaitable*>(p)->location_.line(),-                  static_cast<awaitable*>(p)->location_.function_name()));-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)-              static_cast<Op&&>(static_cast<awaitable*>(p)->op_)(-                  co_composed_handler<Executors, Handler,-                    Return, completion_signature_of_t<Op>>(-                      static_cast<awaitable*>(p)->promise_));-            };-        }-      }--      auto await_resume()-      {-        return co_composed_handler<Executors, Handler, Return,-          completion_signature_of_t<Op>>::on_resume(promise_.result_);-      }--    private:-      Op&& op_;-      co_composed_promise& promise_;-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)-      asio::detail::source_location location_;-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)-    };--    state_.check_for_cancellation_on_transform();-    return awaitable{static_cast<Op&&>(op), *this-#if defined(ASIO_ENABLE_HANDLER_TRACKING)-# if defined(ASIO_HAS_SOURCE_LOCATION)-        , location-# endif // defined(ASIO_HAS_SOURCE_LOCATION)-#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)-      };-  }--  template <typename... Args>-  auto yield_value(co_composed_completion<Args...>&& result)-  {-    class [[nodiscard]] awaitable-    {-    public:-      awaitable(co_composed_completion<Args...>&& result,-          co_composed_promise& promise)-        : result_(std::move(result)),-          promise_(promise)-      {-      }--      constexpr bool await_ready() const noexcept-      {-        return false;-      }--      void await_suspend(coroutine_handle<co_composed_promise>)-      {-        promise_.state_.work_.reset();-        promise_.state_.on_suspend_->arg_ = this;-        promise_.state_.on_suspend_->fn_ =-          [](void* p)-          {-            awaitable& a = *static_cast<awaitable*>(p);--            co_composed_handler_base<Executors, Handler,-              Return> composed_handler(a.promise_);--            Handler handler(std::move(a.promise_.state_.handler_));-            std::tuple<decay_t<Args>...> result(-                std::move(static_cast<std::tuple<Args&&...>&>(a.result_)));--            co_composed_handler_base<Executors, Handler,-              Return>(std::move(composed_handler));--            std::apply(std::move(handler), std::move(result));-          };-      }--      void await_resume() noexcept-      {-      }--    private:-      co_composed_completion<Args...> result_;-      co_composed_promise& promise_;-    };--    return awaitable{std::move(result), *this};-  }--private:-  using allocator_type =-    associated_allocator_t<Handler, recycling_allocator<void>>;--  union block-  {-    std::max_align_t max_align;-    alignas(allocator_type) char pad[alignof(allocator_type)];-  };--  using block_allocator_type =-    typename std::allocator_traits<allocator_type>-      ::template rebind_alloc<block>;--  static constexpr std::size_t blocks(std::size_t size)-  {-    return (size + sizeof(block) - 1) / sizeof(block);-  }--  co_composed_state<Executors, Handler, Return>& state_;-  co_composed_promise** owner_ = nullptr;-  void* result_ = nullptr;-};--template <typename Implementation, typename Executors, typename... Signatures>-class initiate_co_composed-{-public:-  using executor_type = typename composed_io_executors<Executors>::head_type;--  template <typename I>-  initiate_co_composed(I&& impl, composed_io_executors<Executors>&& executors)-    : implementation_(static_cast<I&&>(impl)),-      executors_(std::move(executors))-  {-  }--  executor_type get_executor() const noexcept-  {-    return executors_.head_;-  }--  template <typename Handler, typename... InitArgs>-  void operator()(Handler&& handler, InitArgs&&... init_args) const &-  {-    using handler_type = decay_t<Handler>;-    using returns_type = co_composed_returns<Signatures...>;-    co_composed_on_suspend on_suspend{};-    implementation_(-        co_composed_state<Executors, handler_type, returns_type>(-          executors_, static_cast<Handler&&>(handler), on_suspend),-        static_cast<InitArgs&&>(init_args)...);-    if (on_suspend.fn_)-      on_suspend.fn_(on_suspend.arg_);-  }--  template <typename Handler, typename... InitArgs>-  void operator()(Handler&& handler, InitArgs&&... init_args) &&-  {-    using handler_type = decay_t<Handler>;-    using returns_type = co_composed_returns<Signatures...>;-    co_composed_on_suspend on_suspend{};-    std::move(implementation_)(-        co_composed_state<Executors, handler_type, returns_type>(-          std::move(executors_), static_cast<Handler&&>(handler), on_suspend),-        static_cast<InitArgs&&>(init_args)...);-    if (on_suspend.fn_)-      on_suspend.fn_(on_suspend.arg_);-  }--private:-  Implementation implementation_;-  composed_io_executors<Executors> executors_;-};--template <typename Implementation, typename... Signatures>-class initiate_co_composed<Implementation, void(), Signatures...>-{-public:-  template <typename I>-  initiate_co_composed(I&& impl, composed_io_executors<void()>&&)-    : implementation_(static_cast<I&&>(impl))-  {-  }--  template <typename Handler, typename... InitArgs>-  void operator()(Handler&& handler, InitArgs&&... init_args) const &-  {-    using handler_type = decay_t<Handler>;-    using returns_type = co_composed_returns<Signatures...>;-    co_composed_on_suspend on_suspend{};-    implementation_(-        co_composed_state<void(), handler_type, returns_type>(-          composed_io_executors<void()>(),-          static_cast<Handler&&>(handler), on_suspend),-        static_cast<InitArgs&&>(init_args)...);-    if (on_suspend.fn_)-      on_suspend.fn_(on_suspend.arg_);-  }--  template <typename Handler, typename... InitArgs>-  void operator()(Handler&& handler, InitArgs&&... init_args) &&-  {-    using handler_type = decay_t<Handler>;-    using returns_type = co_composed_returns<Signatures...>;-    co_composed_on_suspend on_suspend{};-    std::move(implementation_)(-        co_composed_state<void(), handler_type, returns_type>(-          composed_io_executors<void()>(),-          static_cast<Handler&&>(handler), on_suspend),-        static_cast<InitArgs&&>(init_args)...);-    if (on_suspend.fn_)-      on_suspend.fn_(on_suspend.arg_);-  }--private:-  Implementation implementation_;-};--template <typename... Signatures, typename Implementation, typename Executors>-inline initiate_co_composed<decay_t<Implementation>, Executors, Signatures...>-make_initiate_co_composed(Implementation&& implementation,-    composed_io_executors<Executors>&& executors)-{-  return initiate_co_composed<-    decay_t<Implementation>, Executors, Signatures...>(-        static_cast<Implementation&&>(implementation), std::move(executors));-}--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename Executors, typename Handler, typename Return,-    typename Signature, typename DefaultCandidate>-struct associator<Associator,-    detail::co_composed_handler<Executors, Handler, Return, Signature>,-    DefaultCandidate>-  : Associator<Handler, DefaultCandidate>-{-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::co_composed_handler<-        Executors, Handler, Return, Signature>& h) noexcept-  {-    return Associator<Handler, DefaultCandidate>::get(-        h.promise().state().handler());-  }--  static auto get(-      const detail::co_composed_handler<-        Executors, Handler, Return, Signature>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(-      Associator<Handler, DefaultCandidate>::get(-        h.promise().state().handler(), c))-  {-    return Associator<Handler, DefaultCandidate>::get(-        h.promise().state().handler(), c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--} // namespace asio--#if !defined(GENERATING_DOCUMENTATION)-# if defined(ASIO_HAS_STD_COROUTINE)-namespace std {-# else // defined(ASIO_HAS_STD_COROUTINE)-namespace std { namespace experimental {-# endif // defined(ASIO_HAS_STD_COROUTINE)--template <typename C, typename Executors,-    typename Handler, typename Return, typename... Args>-struct coroutine_traits<void, C&,-    asio::detail::co_composed_state<Executors, Handler, Return>, Args...>-{-  using promise_type =-    asio::detail::co_composed_promise<Executors, Handler, Return>;-};--template <typename C, typename Executors,-    typename Handler, typename Return, typename... Args>-struct coroutine_traits<void, C&&,-    asio::detail::co_composed_state<Executors, Handler, Return>, Args...>-{-  using promise_type =-    asio::detail::co_composed_promise<Executors, Handler, Return>;-};--template <typename Executors, typename Handler,-    typename Return, typename... Args>-struct coroutine_traits<void,-    asio::detail::co_composed_state<Executors, Handler, Return>, Args...>-{-  using promise_type =-    asio::detail::co_composed_promise<Executors, Handler, Return>;-};--# if defined(ASIO_HAS_STD_COROUTINE)-} // namespace std-# else // defined(ASIO_HAS_STD_COROUTINE)-}} // namespace std::experimental-# endif // defined(ASIO_HAS_STD_COROUTINE)-#endif // !defined(GENERATING_DOCUMENTATION)--namespace asio {--/// Creates an initiation function object that may be used to launch a-/// coroutine-based composed asynchronous operation.-/**- * The co_composed utility simplifies the implementation of composed- * asynchronous operations by automatically adapting a coroutine to be an- * initiation function object for use with @c async_initiate. When awaiting- * asynchronous operations, the coroutine automatically uses a conforming- * intermediate completion handler.- *- * @param implementation A function object that contains the coroutine-based- * implementation of the composed asynchronous operation. The first argument to- * the function object represents the state of the operation, and may be used- * to test for cancellation. The remaining arguments are those passed to @c- * async_initiate after the completion token.- *- * @param io_objects_or_executors Zero or more I/O objects or I/O executors for- * which outstanding work must be maintained while the operation is incomplete.- *- * @par Per-Operation Cancellation- * By default, terminal per-operation cancellation is enabled for composed- * operations that use co_composed. To disable cancellation for the composed- * operation, or to alter its supported cancellation types, call the state's- * @c reset_cancellation_state function.- *- * @par Examples- * The following example illustrates manual error handling and explicit checks- * for cancellation. The completion handler is invoked via a @c co_yield to the- * state's @c complete function, which never returns.- *- * @code template <typename CompletionToken>- * auto async_echo(tcp::socket& socket,- *     CompletionToken&& token)- * {- *   return asio::async_initiate<- *     CompletionToken, void(std::error_code)>(- *       asio::co_composed(- *         [](auto state, tcp::socket& socket) -> void- *         {- *           state.reset_cancellation_state(- *             asio::enable_terminal_cancellation());- *- *           while (!state.cancelled())- *           {- *             char data[1024];- *             auto [e1, n1] =- *               co_await socket.async_read_some(- *                 asio::buffer(data));- *- *             if (e1)- *               co_yield state.complete(e1);- *- *             if (!!state.cancelled())- *               co_yield state.complete(- *                 make_error_code(asio::error::operation_aborted));- *- *             auto [e2, n2] =- *               co_await asio::async_write(socket,- *                 asio::buffer(data, n1));- *- *             if (e2)- *               co_yield state.complete(e2);- *           }- *         }, socket),- *       token, std::ref(socket));- * } @endcode- *- * This next example shows exception-based error handling and implicit checks- * for cancellation. The completion handler is invoked after returning from the- * coroutine via @c co_return. Valid @c co_return values are specified using- * completion signatures passed to the @c co_composed function.- *- * @code template <typename CompletionToken>- * auto async_echo(tcp::socket& socket,- *     CompletionToken&& token)- * {- *   return asio::async_initiate<- *     CompletionToken, void(std::error_code)>(- *       asio::co_composed<- *         void(std::error_code)>(- *           [](auto state, tcp::socket& socket) -> void- *           {- *             try- *             {- *               state.throw_if_cancelled(true);- *               state.reset_cancellation_state(- *                 asio::enable_terminal_cancellation());- *- *               for (;;)- *               {- *                 char data[1024];- *                 std::size_t n = co_await socket.async_read_some(- *                     asio::buffer(data));- *- *                 co_await asio::async_write(socket,- *                     asio::buffer(data, n));- *               }- *             }- *             catch (const std::system_error& e)- *             {- *               co_return {e.code()};- *             }- *           }, socket),- *       token, std::ref(socket));- * } @endcode- */-template <ASIO_COMPLETION_SIGNATURE... Signatures,-    typename Implementation, typename... IoObjectsOrExecutors>-inline auto co_composed(Implementation&& implementation,-    IoObjectsOrExecutors&&... io_objects_or_executors)-{-  return detail::make_initiate_co_composed<Signatures...>(-      static_cast<Implementation&&>(implementation),-      detail::make_composed_io_executors(-        detail::get_composed_io_executor(-          static_cast<IoObjectsOrExecutors&&>(-            io_objects_or_executors))...));-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)--#endif // ASIO_CO_COMPOSED_HPP
link/modules/asio-standalone/asio/include/asio/co_spawn.hpp view
@@ -2,7 +2,7 @@ // co_spawn.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -113,10 +113,10 @@ co_spawn(const Executor& ex, awaitable<T, AwaitableExecutor> a,     CompletionToken&& token       ASIO_DEFAULT_COMPLETION_TOKEN(Executor),-    constraint_t<+    typename constraint<       (is_executor<Executor>::value || execution::is_executor<Executor>::value)         && is_convertible<Executor, AwaitableExecutor>::value-    > = 0);+    >::type = 0);  /// Spawn a new coroutined-based thread of execution. /**@@ -177,10 +177,10 @@ co_spawn(const Executor& ex, awaitable<void, AwaitableExecutor> a,     CompletionToken&& token       ASIO_DEFAULT_COMPLETION_TOKEN(Executor),-    constraint_t<+    typename constraint<       (is_executor<Executor>::value || execution::is_executor<Executor>::value)         && is_convertible<Executor, AwaitableExecutor>::value-    > = 0);+    >::type = 0);  /// Spawn a new coroutined-based thread of execution. /**@@ -251,11 +251,11 @@     CompletionToken&& token       ASIO_DEFAULT_COMPLETION_TOKEN(         typename ExecutionContext::executor_type),-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value         && is_convertible<typename ExecutionContext::executor_type,           AwaitableExecutor>::value-    > = 0);+    >::type = 0);  /// Spawn a new coroutined-based thread of execution. /**@@ -318,11 +318,11 @@     CompletionToken&& token       ASIO_DEFAULT_COMPLETION_TOKEN(         typename ExecutionContext::executor_type),-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value         && is_convertible<typename ExecutionContext::executor_type,           AwaitableExecutor>::value-    > = 0);+    >::type = 0);  /// Spawn a new coroutined-based thread of execution. /**@@ -406,16 +406,16 @@  */ template <typename Executor, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<-      result_of_t<F()>>::type) CompletionToken+      typename result_of<F()>::type>::type) CompletionToken         ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)> ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,-    typename detail::awaitable_signature<result_of_t<F()>>::type)+    typename detail::awaitable_signature<typename result_of<F()>::type>::type) co_spawn(const Executor& ex, F&& f,     CompletionToken&& token       ASIO_DEFAULT_COMPLETION_TOKEN(Executor),-    constraint_t<+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0);+    >::type = 0);  /// Spawn a new coroutined-based thread of execution. /**@@ -499,18 +499,18 @@  */ template <typename ExecutionContext, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<-      result_of_t<F()>>::type) CompletionToken+      typename result_of<F()>::type>::type) CompletionToken         ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(           typename ExecutionContext::executor_type)> ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,-    typename detail::awaitable_signature<result_of_t<F()>>::type)+    typename detail::awaitable_signature<typename result_of<F()>::type>::type) co_spawn(ExecutionContext& ctx, F&& f,     CompletionToken&& token       ASIO_DEFAULT_COMPLETION_TOKEN(         typename ExecutionContext::executor_type),-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    > = 0);+    >::type = 0);  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/completion_condition.hpp view
@@ -2,7 +2,7 @@ // completion_condition.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,8 +17,6 @@  #include "asio/detail/config.hpp" #include <cstddef>-#include "asio/detail/type_traits.hpp"-#include "asio/error_code.hpp"  #include "asio/detail/push_options.hpp" @@ -99,54 +97,7 @@   std::size_t size_; }; -template <typename T, typename = void>-struct is_completion_condition_helper : false_type-{-};--template <typename T>-struct is_completion_condition_helper<T,-    enable_if_t<-      is_same<-        result_of_t<T(asio::error_code, std::size_t)>,-        bool-      >::value-    >-  > : true_type-{-};--template <typename T>-struct is_completion_condition_helper<T,-    enable_if_t<-      is_same<-        result_of_t<T(asio::error_code, std::size_t)>,-        std::size_t-      >::value-    >-  > : true_type-{-};- } // namespace detail--#if defined(GENERATING_DOCUMENTATION)--/// Trait for determining whether a function object is a completion condition.-template <typename T>-struct is_completion_condition-{-  static constexpr bool value = automatically_determined;-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename T>-struct is_completion_condition : detail::is_completion_condition_helper<T>-{-};--#endif // defined(GENERATING_DOCUMENTATION)  /**  * @defgroup completion_condition Completion Condition Function Objects
link/modules/asio-standalone/asio/include/asio/compose.hpp view
@@ -2,7 +2,7 @@ // compose.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,12 +16,311 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include "asio/composed.hpp"+#include "asio/associated_executor.hpp"+#include "asio/async_result.hpp"+#include "asio/detail/base_from_cancellation_state.hpp"+#include "asio/detail/composed_work.hpp"+#include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp"  namespace asio {+namespace detail { +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+template <typename Impl, typename Work, typename Handler, typename Signature>+class composed_op;++template <typename Impl, typename Work, typename Handler,+    typename R, typename... Args>+class composed_op<Impl, Work, Handler, R(Args...)>+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+template <typename Impl, typename Work, typename Handler, typename Signature>+class composed_op+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+  : public base_from_cancellation_state<Handler>+{+public:+  template <typename I, typename W, typename H>+  composed_op(ASIO_MOVE_ARG(I) impl,+      ASIO_MOVE_ARG(W) work,+      ASIO_MOVE_ARG(H) handler)+    : base_from_cancellation_state<Handler>(+        handler, enable_terminal_cancellation()),+      impl_(ASIO_MOVE_CAST(I)(impl)),+      work_(ASIO_MOVE_CAST(W)(work)),+      handler_(ASIO_MOVE_CAST(H)(handler)),+      invocations_(0)+  {+  }++#if defined(ASIO_HAS_MOVE)+  composed_op(composed_op&& other)+    : base_from_cancellation_state<Handler>(+        ASIO_MOVE_CAST(base_from_cancellation_state<+          Handler>)(other)),+      impl_(ASIO_MOVE_CAST(Impl)(other.impl_)),+      work_(ASIO_MOVE_CAST(Work)(other.work_)),+      handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+      invocations_(other.invocations_)+  {+  }+#endif // defined(ASIO_HAS_MOVE)++  typedef typename composed_work_guard<+    typename Work::head_type>::executor_type io_executor_type;++  io_executor_type get_io_executor() const ASIO_NOEXCEPT+  {+    return work_.head_.get_executor();+  }++  typedef typename associated_executor<Handler, io_executor_type>::type+    executor_type;++  executor_type get_executor() const ASIO_NOEXCEPT+  {+    return (get_associated_executor)(handler_, work_.head_.get_executor());+  }++  typedef typename associated_allocator<Handler,+    std::allocator<void> >::type allocator_type;++  allocator_type get_allocator() const ASIO_NOEXCEPT+  {+    return (get_associated_allocator)(handler_, std::allocator<void>());+  }++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template<typename... T>+  void operator()(ASIO_MOVE_ARG(T)... t)+  {+    if (invocations_ < ~0u)+      ++invocations_;+    this->get_cancellation_state().slot().clear();+    impl_(*this, ASIO_MOVE_CAST(T)(t)...);+  }++  void complete(Args... args)+  {+    this->work_.reset();+    ASIO_MOVE_OR_LVALUE(Handler)(this->handler_)(+        ASIO_MOVE_CAST(Args)(args)...);+  }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  void operator()()+  {+    if (invocations_ < ~0u)+      ++invocations_;+    this->get_cancellation_state().slot().clear();+    impl_(*this);+  }++  void complete()+  {+    this->work_.reset();+    ASIO_MOVE_OR_LVALUE(Handler)(this->handler_)();+  }++#define ASIO_PRIVATE_COMPOSED_OP_DEF(n) \+  template<ASIO_VARIADIC_TPARAMS(n)> \+  void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    if (invocations_ < ~0u) \+      ++invocations_; \+    this->get_cancellation_state().slot().clear(); \+    impl_(*this, ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template<ASIO_VARIADIC_TPARAMS(n)> \+  void complete(ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    this->work_.reset(); \+    ASIO_MOVE_OR_LVALUE(Handler)(this->handler_)( \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPOSED_OP_DEF)+#undef ASIO_PRIVATE_COMPOSED_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  void reset_cancellation_state()+  {+    base_from_cancellation_state<Handler>::reset_cancellation_state(handler_);+  }++  template <typename Filter>+  void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter)+  {+    base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,+        ASIO_MOVE_CAST(Filter)(filter));+  }++  template <typename InFilter, typename OutFilter>+  void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,+      ASIO_MOVE_ARG(OutFilter) out_filter)+  {+    base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,+        ASIO_MOVE_CAST(InFilter)(in_filter),+        ASIO_MOVE_CAST(OutFilter)(out_filter));+  }++  cancellation_type_t cancelled() const ASIO_NOEXCEPT+  {+    return base_from_cancellation_state<Handler>::cancelled();+  }++//private:+  Impl impl_;+  Work work_;+  Handler handler_;+  unsigned invocations_;+};++template <typename Impl, typename Work, typename Handler, typename Signature>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    composed_op<Impl, Work, Handler, Signature>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Impl, typename Work, typename Handler, typename Signature>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    composed_op<Impl, Work, Handler, Signature>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Impl, typename Work, typename Handler, typename Signature>+inline bool asio_handler_is_continuation(+    composed_op<Impl, Work, Handler, Signature>* this_handler)+{+  return this_handler->invocations_ > 1 ? true+    : asio_handler_cont_helpers::is_continuation(+        this_handler->handler_);+}++template <typename Function, typename Impl,+    typename Work, typename Handler, typename Signature>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    composed_op<Impl, Work, Handler, Signature>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Impl,+    typename Work, typename Handler, typename Signature>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    composed_op<Impl, Work, Handler, Signature>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Signature, typename Executors>+class initiate_composed_op+{+public:+  typedef typename composed_io_executors<Executors>::head_type executor_type;++  template <typename T>+  explicit initiate_composed_op(int, ASIO_MOVE_ARG(T) executors)+    : executors_(ASIO_MOVE_CAST(T)(executors))+  {+  }++  executor_type get_executor() const ASIO_NOEXCEPT+  {+    return executors_.head_;+  }++  template <typename Handler, typename Impl>+  void operator()(ASIO_MOVE_ARG(Handler) handler,+      ASIO_MOVE_ARG(Impl) impl) const+  {+    composed_op<typename decay<Impl>::type, composed_work<Executors>,+      typename decay<Handler>::type, Signature>(+        ASIO_MOVE_CAST(Impl)(impl),+        composed_work<Executors>(executors_),+        ASIO_MOVE_CAST(Handler)(handler))();+  }++private:+  composed_io_executors<Executors> executors_;+};++template <typename Signature, typename Executors>+inline initiate_composed_op<Signature, Executors> make_initiate_composed_op(+    ASIO_MOVE_ARG(composed_io_executors<Executors>) executors)+{+  return initiate_composed_op<Signature, Executors>(0,+      ASIO_MOVE_CAST(composed_io_executors<Executors>)(executors));+}++} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename Impl, typename Work, typename Handler,+    typename Signature, typename DefaultCandidate>+struct associator<Associator,+    detail::composed_op<Impl, Work, Handler, Signature>,+    DefaultCandidate>+  : Associator<Handler, DefaultCandidate>+{+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::composed_op<Impl, Work, Handler, Signature>& h)+    ASIO_NOEXCEPT+  {+    return Associator<Handler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::composed_op<Impl, Work, Handler, Signature>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<Handler, DefaultCandidate>::get(h.handler_, c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)+ /// Launch an asynchronous operation with a stateful implementation. /**  * The async_compose function simplifies the implementation of composed@@ -40,13 +339,6 @@  * @param io_objects_or_executors Zero or more I/O objects or I/O executors for  * which outstanding work must be maintained.  *- * @par Per-Operation Cancellation- * By default, terminal per-operation cancellation is enabled for- * composed operations that are implemented using @c async_compose. To- * disable cancellation for the composed operation, or to alter its- * supported cancellation types, call the @c self object's @c- * reset_cancellation_state function.- *  * @par Example:  *  * @code struct async_echo_implementation@@ -90,8 +382,8 @@  * template <typename CompletionToken>  * auto async_echo(tcp::socket& socket,  *     asio::mutable_buffer buffer,- *     CompletionToken&& token)- *   -> decltype(+ *     CompletionToken&& token) ->+ *   decltype(  *     asio::async_compose<CompletionToken,  *       void(asio::error_code, std::size_t)>(  *         std::declval<async_echo_implementation>(),@@ -106,20 +398,131 @@  */ template <typename CompletionToken, typename Signature,     typename Implementation, typename... IoObjectsOrExecutors>-inline auto async_compose(Implementation&& implementation,-    type_identity_t<CompletionToken>& token,-    IoObjectsOrExecutors&&... io_objects_or_executors)-  -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, Signature)+async_compose(ASIO_MOVE_ARG(Implementation) implementation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,+    ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken, Signature>(-      composed<Signature>(static_cast<Implementation&&>(implementation),-        static_cast<IoObjectsOrExecutors&&>(io_objects_or_executors)...),-      token))+        detail::make_initiate_composed_op<Signature>(+          detail::make_composed_io_executors(+            detail::get_composed_io_executor(+              ASIO_MOVE_CAST(IoObjectsOrExecutors)(+                io_objects_or_executors))...)),+        token, ASIO_MOVE_CAST(Implementation)(implementation)))) {   return async_initiate<CompletionToken, Signature>(-      composed<Signature>(static_cast<Implementation&&>(implementation),-        static_cast<IoObjectsOrExecutors&&>(io_objects_or_executors)...),-      token);+      detail::make_initiate_composed_op<Signature>(+        detail::make_composed_io_executors(+          detail::get_composed_io_executor(+            ASIO_MOVE_CAST(IoObjectsOrExecutors)(+              io_objects_or_executors))...)),+      token, ASIO_MOVE_CAST(Implementation)(implementation)); }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+      //   || defined(GENERATING_DOCUMENTATION)++template <typename CompletionToken, typename Signature, typename Implementation>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, Signature)+async_compose(ASIO_MOVE_ARG(Implementation) implementation,+    ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<CompletionToken, Signature>(+        detail::make_initiate_composed_op<Signature>(+          detail::make_composed_io_executors()),+        token, ASIO_MOVE_CAST(Implementation)(implementation))))+{+  return async_initiate<CompletionToken, Signature>(+      detail::make_initiate_composed_op<Signature>(+        detail::make_composed_io_executors()),+      token, ASIO_MOVE_CAST(Implementation)(implementation));+}++# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n) \+  ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_##n++# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1 \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2 \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3 \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4 \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5 \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T5)(x5))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_6 \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T5)(x5)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T6)(x6))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_7 \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T5)(x5)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T6)(x6)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T7)(x7))+# define ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_8 \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T1)(x1)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T2)(x2)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T3)(x3)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T4)(x4)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T5)(x5)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T6)(x6)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T7)(x7)), \+  detail::get_composed_io_executor(ASIO_MOVE_CAST(T8)(x8))++#define ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \+  template <typename CompletionToken, typename Signature, \+      typename Implementation, ASIO_VARIADIC_TPARAMS(n)> \+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, Signature) \+  async_compose(ASIO_MOVE_ARG(Implementation) implementation, \+      ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( \+      async_initiate<CompletionToken, Signature>( \+          detail::make_initiate_composed_op<Signature>( \+            detail::make_composed_io_executors( \+              ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))), \+          token, ASIO_MOVE_CAST(Implementation)(implementation)))) \+  { \+    return async_initiate<CompletionToken, Signature>( \+        detail::make_initiate_composed_op<Signature>( \+          detail::make_composed_io_executors( \+            ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))), \+        token, ASIO_MOVE_CAST(Implementation)(implementation)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_COMPOSE_DEF)+#undef ASIO_PRIVATE_ASYNC_COMPOSE_DEF++#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_6+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_7+#undef ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_8++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)  } // namespace asio 
− link/modules/asio-standalone/asio/include/asio/composed.hpp
@@ -1,413 +0,0 @@-//-// composed.hpp-// ~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_COMPOSED_HPP-#define ASIO_COMPOSED_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/detail/base_from_cancellation_state.hpp"-#include "asio/detail/composed_work.hpp"-#include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Impl, typename Work,-    typename Handler, typename... Signatures>-class composed_op;--template <typename Impl, typename Work, typename Handler>-class composed_op<Impl, Work, Handler>-  : public base_from_cancellation_state<Handler>-{-public:-  template <typename I, typename W, typename H>-  composed_op(I&& impl,-      W&& work,-      H&& handler)-    : base_from_cancellation_state<Handler>(-        handler, enable_terminal_cancellation()),-      impl_(static_cast<I&&>(impl)),-      work_(static_cast<W&&>(work)),-      handler_(static_cast<H&&>(handler)),-      invocations_(0)-  {-  }--  composed_op(composed_op&& other)-    : base_from_cancellation_state<Handler>(-        static_cast<base_from_cancellation_state<Handler>&&>(other)),-      impl_(static_cast<Impl&&>(other.impl_)),-      work_(static_cast<Work&&>(other.work_)),-      handler_(static_cast<Handler&&>(other.handler_)),-      invocations_(other.invocations_)-  {-  }--  typedef typename composed_work_guard<-    typename Work::head_type>::executor_type io_executor_type;--  io_executor_type get_io_executor() const noexcept-  {-    return work_.head_.get_executor();-  }--  typedef associated_executor_t<Handler, io_executor_type> executor_type;--  executor_type get_executor() const noexcept-  {-    return (get_associated_executor)(handler_, work_.head_.get_executor());-  }--  typedef associated_allocator_t<Handler, std::allocator<void>> allocator_type;--  allocator_type get_allocator() const noexcept-  {-    return (get_associated_allocator)(handler_, std::allocator<void>());-  }--  template <typename... T>-  void operator()(T&&... t)-  {-    if (invocations_ < ~0u)-      ++invocations_;-    this->get_cancellation_state().slot().clear();-    impl_(*this, static_cast<T&&>(t)...);-  }--  template <typename... Args>-  auto complete(Args&&... args)-    -> decltype(declval<Handler>()(static_cast<Args&&>(args)...))-  {-    return static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);-  }--  void reset_cancellation_state()-  {-    base_from_cancellation_state<Handler>::reset_cancellation_state(handler_);-  }--  template <typename Filter>-  void reset_cancellation_state(Filter&& filter)-  {-    base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,-        static_cast<Filter&&>(filter));-  }--  template <typename InFilter, typename OutFilter>-  void reset_cancellation_state(InFilter&& in_filter,-      OutFilter&& out_filter)-  {-    base_from_cancellation_state<Handler>::reset_cancellation_state(handler_,-        static_cast<InFilter&&>(in_filter),-        static_cast<OutFilter&&>(out_filter));-  }--  cancellation_type_t cancelled() const noexcept-  {-    return base_from_cancellation_state<Handler>::cancelled();-  }--//private:-  Impl impl_;-  Work work_;-  Handler handler_;-  unsigned invocations_;-};--template <typename Impl, typename Work, typename Handler,-    typename R, typename... Args>-class composed_op<Impl, Work, Handler, R(Args...)>-  : public composed_op<Impl, Work, Handler>-{-public:-  using composed_op<Impl, Work, Handler>::composed_op;--  template <typename... T>-  void operator()(T&&... t)-  {-    if (this->invocations_ < ~0u)-      ++this->invocations_;-    this->get_cancellation_state().slot().clear();-    this->impl_(*this, static_cast<T&&>(t)...);-  }--  void complete(Args... args)-  {-    this->work_.reset();-    static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);-  }-};--template <typename Impl, typename Work, typename Handler,-    typename R, typename... Args, typename... Signatures>-class composed_op<Impl, Work, Handler, R(Args...), Signatures...>-  : public composed_op<Impl, Work, Handler, Signatures...>-{-public:-  using composed_op<Impl, Work, Handler, Signatures...>::composed_op;--  template <typename... T>-  void operator()(T&&... t)-  {-    if (this->invocations_ < ~0u)-      ++this->invocations_;-    this->get_cancellation_state().slot().clear();-    this->impl_(*this, static_cast<T&&>(t)...);-  }--  using composed_op<Impl, Work, Handler, Signatures...>::complete;--  void complete(Args... args)-  {-    this->work_.reset();-    static_cast<Handler&&>(this->handler_)(static_cast<Args&&>(args)...);-  }-};--template <typename Impl, typename Work, typename Handler, typename Signature>-inline bool asio_handler_is_continuation(-    composed_op<Impl, Work, Handler, Signature>* this_handler)-{-  return this_handler->invocations_ > 1 ? true-    : asio_handler_cont_helpers::is_continuation(-        this_handler->handler_);-}--template <typename Implementation, typename Executors, typename... Signatures>-class initiate_composed-{-public:-  typedef typename composed_io_executors<Executors>::head_type executor_type;--  template <typename I>-  initiate_composed(I&& impl, composed_io_executors<Executors>&& executors)-    : implementation_(std::forward<I>(impl)),-      executors_(std::move(executors))-  {-  }--  executor_type get_executor() const noexcept-  {-    return executors_.head_;-  }--  template <typename Handler, typename... Args>-  void operator()(Handler&& handler, Args&&... args) const &-  {-    composed_op<decay_t<Implementation>, composed_work<Executors>,-      decay_t<Handler>, Signatures...>(implementation_,-        composed_work<Executors>(executors_),-        static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);-  }--  template <typename Handler, typename... Args>-  void operator()(Handler&& handler, Args&&... args) &&-  {-    composed_op<decay_t<Implementation>, composed_work<Executors>,-      decay_t<Handler>, Signatures...>(-        static_cast<Implementation&&>(implementation_),-        composed_work<Executors>(executors_),-        static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);-  }--private:-  Implementation implementation_;-  composed_io_executors<Executors> executors_;-};--template <typename Implementation, typename... Signatures>-class initiate_composed<Implementation, void(), Signatures...>-{-public:-  template <typename I>-  initiate_composed(I&& impl, composed_io_executors<void()>&&)-    : implementation_(std::forward<I>(impl))-  {-  }--  template <typename Handler, typename... Args>-  void operator()(Handler&& handler, Args&&... args) const &-  {-    composed_op<decay_t<Implementation>, composed_work<void()>,-      decay_t<Handler>, Signatures...>(implementation_,-        composed_work<void()>(composed_io_executors<void()>()),-        static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);-  }--  template <typename Handler, typename... Args>-  void operator()(Handler&& handler, Args&&... args) &&-  {-    composed_op<decay_t<Implementation>, composed_work<void()>,-      decay_t<Handler>, Signatures...>(-        static_cast<Implementation&&>(implementation_),-        composed_work<void()>(composed_io_executors<void()>()),-        static_cast<Handler&&>(handler))(static_cast<Args&&>(args)...);-  }--private:-  Implementation implementation_;-};--template <typename... Signatures, typename Implementation, typename Executors>-inline initiate_composed<Implementation, Executors, Signatures...>-make_initiate_composed(Implementation&& implementation,-    composed_io_executors<Executors>&& executors)-{-  return initiate_composed<decay_t<Implementation>, Executors, Signatures...>(-      static_cast<Implementation&&>(implementation),-      static_cast<composed_io_executors<Executors>&&>(executors));-}--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename Impl, typename Work, typename Handler,-    typename Signature, typename DefaultCandidate>-struct associator<Associator,-    detail::composed_op<Impl, Work, Handler, Signature>,-    DefaultCandidate>-  : Associator<Handler, DefaultCandidate>-{-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::composed_op<Impl, Work, Handler, Signature>& h) noexcept-  {-    return Associator<Handler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(const detail::composed_op<Impl, Work, Handler, Signature>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<Handler, DefaultCandidate>::get(h.handler_, c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--/// Creates an initiation function object that may be used to launch an-/// asynchronous operation with a stateful implementation.-/**- * The @c composed function simplifies the implementation of composed- * asynchronous operations automatically by wrapping a stateful function object- * for use as an initiation function object.- *- * @param implementation A function object that contains the implementation of- * the composed asynchronous operation. The first argument to the function- * object is a non-const reference to the enclosing intermediate completion- * handler. The remaining arguments are any arguments that originate from the- * completion handlers of any asynchronous operations performed by the- * implementation.- *- * @param io_objects_or_executors Zero or more I/O objects or I/O executors for- * which outstanding work must be maintained.- *- * @par Per-Operation Cancellation- * By default, terminal per-operation cancellation is enabled for composed- * operations that are implemented using @c composed. To disable cancellation- * for the composed operation, or to alter its supported cancellation types,- * call the @c self object's @c reset_cancellation_state function.- *- * @par Example:- *- * @code struct async_echo_implementation- * {- *   tcp::socket& socket_;- *   asio::mutable_buffer buffer_;- *   enum { starting, reading, writing } state_;- *- *   template <typename Self>- *   void operator()(Self& self,- *       asio::error_code error,- *       std::size_t n)- *   {- *     switch (state_)- *     {- *     case starting:- *       state_ = reading;- *       socket_.async_read_some(- *           buffer_, std::move(self));- *       break;- *     case reading:- *       if (error)- *       {- *         self.complete(error, 0);- *       }- *       else- *       {- *         state_ = writing;- *         asio::async_write(socket_, buffer_,- *             asio::transfer_exactly(n),- *             std::move(self));- *       }- *       break;- *     case writing:- *       self.complete(error, n);- *       break;- *     }- *   }- * };- *- * template <typename CompletionToken>- * auto async_echo(tcp::socket& socket,- *     asio::mutable_buffer buffer,- *     CompletionToken&& token)- *   -> decltype(- *     asio::async_initiate<CompletionToken,- *       void(asio::error_code, std::size_t)>(- *         asio::composed(- *           async_echo_implementation{socket, buffer,- *             async_echo_implementation::starting}, socket),- *         token))- * {- *   return asio::async_initiate<CompletionToken,- *     void(asio::error_code, std::size_t)>(- *       asio::composed(- *         async_echo_implementation{socket, buffer,- *           async_echo_implementation::starting}, socket),- *       token, asio::error_code{}, 0);- * } @endcode- */-template <ASIO_COMPLETION_SIGNATURE... Signatures,-    typename Implementation, typename... IoObjectsOrExecutors>-inline auto composed(Implementation&& implementation,-    IoObjectsOrExecutors&&... io_objects_or_executors)-  -> decltype(-    detail::make_initiate_composed<Signatures...>(-      static_cast<Implementation&&>(implementation),-      detail::make_composed_io_executors(-        detail::get_composed_io_executor(-          static_cast<IoObjectsOrExecutors&&>(-            io_objects_or_executors))...)))-{-  return detail::make_initiate_composed<Signatures...>(-      static_cast<Implementation&&>(implementation),-      detail::make_composed_io_executors(-        detail::get_composed_io_executor(-          static_cast<IoObjectsOrExecutors&&>(-            io_objects_or_executors))...));-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_COMPOSE_HPP
− link/modules/asio-standalone/asio/include/asio/config.hpp
@@ -1,193 +0,0 @@-//-// config.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_CONFIG_HPP-#define ASIO_CONFIG_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/throw_exception.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/execution_context.hpp"-#include <cstddef>-#include <string>--#include "asio/detail/push_options.hpp"--namespace asio {--/// Base class for configuration implementations.-class config_service :-#if defined(GENERATING_DOCUMENTATION)-  public execution_context::service-#else // defined(GENERATING_DOCUMENTATION)-  public detail::execution_context_service_base<config_service>-#endif // defined(GENERATING_DOCUMENTATION)-{-public:-#if defined(GENERATING_DOCUMENTATION)-  typedef config_service key_type;-#endif // defined(GENERATING_DOCUMENTATION)--  /// Constructor.-  ASIO_DECL explicit config_service(execution_context& ctx);--  /// Shutdown the service.-  ASIO_DECL void shutdown() override;--  /// Retrieve a configuration value.-  ASIO_DECL virtual const char* get_value(const char* section,-      const char* key_name, char* value, std::size_t value_len) const;-};--/// Provides access to the configuration values associated with an execution-/// context.-class config-{-public:-  /// Constructor.-  /**-   * This constructor initialises a @c config object to retrieve configuration-   * values associated with the specified execution context.-   */-  explicit config(execution_context& context)-    : service_(use_service<config_service>(context))-  {-  }--  /// Copy constructor.-  config(const config& other) noexcept-    : service_(other.service_)-  {-  }--  /// Retrieve an integral configuration value.-  template <typename T>-  constraint_t<is_integral<T>::value, T>-  get(const char* section, const char* key_name, T default_value) const;--private:-  config_service& service_;-};--/// Configures an execution context based on a concurrency hint.-/**- * This configuration service is provided for backwards compatibility with- * the existing concurrency hint mechanism.- *- * @par Example- * @code asio::io_context my_io_context{- *     asio::config_from_concurrency_hint{1}}; @endcode- */-class config_from_concurrency_hint : public execution_context::service_maker-{-public:-  /// Construct with a default concurrency hint.-  ASIO_DECL config_from_concurrency_hint();--  /// Construct with a specified concurrency hint.-  explicit config_from_concurrency_hint(int concurrency_hint)-    : concurrency_hint_(concurrency_hint)-  {-  }--  /// Add a concrete service to the specified execution context.-  ASIO_DECL void make(execution_context& ctx) const override;--private:-  int concurrency_hint_;-};--/// Configures an execution context by reading variables from a string.-/**- * Each variable must be on a line of its own, and of the form:- *- * <tt>section.key=value</tt>- *- * or, if an optional prefix is specified:- *- * <tt>prefix.section.key=value</tt>- *- * Blank lines and lines starting with <tt>#</tt> are ignored. It is also- * permitted to include a comment starting with <tt>#</tt> after the value.- *- * @par Example- * @code asio::io_context my_io_context{- *     asio::config_from_string{- *       "scheduler.concurrency_hint=10\n"- *       "scheduler.locking=1"}}; @endcode- */-class config_from_string : public execution_context::service_maker-{-public:-  /// Construct with the default prefix "asio".-  explicit config_from_string(std::string s)-    : string_(static_cast<std::string&&>(s)),-      prefix_()-  {-  }--  /// Construct with a specified prefix.-  config_from_string(std::string s, std::string prefix)-    : string_(static_cast<std::string&&>(s)),-      prefix_(static_cast<std::string&&>(prefix))-  {-  }--  /// Add a concrete service to the specified execution context.-  ASIO_DECL void make(execution_context& ctx) const override;--private:-  std::string string_;-  std::string prefix_;-};--/// Configures an execution context by reading environment variables.-/**- * The environment variable names are formed by concatenating the prefix,- * section, and key, with underscore as delimiter, and then converting the- * resulting string to upper case.- *- * @par Example- * @code asio::io_context my_io_context{- *     asio::config_from_env{"my_app"}}; @endcode- */-class config_from_env : public execution_context::service_maker-{-public:-  /// Construct with the default prefix "asio".-  ASIO_DECL config_from_env();--  /// Construct with a specified prefix.-  explicit config_from_env(std::string prefix)-    : prefix_(static_cast<std::string&&>(prefix))-  {-  }--  /// Add a concrete service to the specified execution context.-  ASIO_DECL void make(execution_context& ctx) const override;--private:-  std::string prefix_;-};--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/impl/config.hpp"-#if defined(ASIO_HEADER_ONLY)-# include "asio/impl/config.ipp"-#endif // defined(ASIO_HEADER_ONLY)--#endif // ASIO_CONFIG_HPP
link/modules/asio-standalone/asio/include/asio/connect.hpp view
@@ -2,7 +2,7 @@ // connect.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -31,97 +31,34 @@   template <typename, typename> class initiate_async_range_connect;   template <typename, typename> class initiate_async_iterator_connect; -  template <typename T, typename = void, typename = void>-  struct is_endpoint_sequence_helper : false_type-  {-  };+  char (&has_iterator_helper(...))[2];    template <typename T>-  struct is_endpoint_sequence_helper<T,-      void_t<-        decltype(declval<T>().begin())-      >,-      void_t<-        decltype(declval<T>().end())-      >-    > : true_type-  {-  };--  template <typename T, typename Iterator, typename = void>-  struct is_connect_condition_helper : false_type-  {-  };--  template <typename T, typename Iterator>-  struct is_connect_condition_helper<T, Iterator,-      enable_if_t<-        is_same<-          result_of_t<T(asio::error_code, Iterator)>,-          Iterator-        >::value-      >-    > : true_type-  {-  };--  template <typename T, typename Iterator>-  struct is_connect_condition_helper<T, Iterator,-      enable_if_t<-        is_same<-          result_of_t<T(asio::error_code,-            decltype(*declval<Iterator>()))>,-          bool-        >::value-      >-    > : true_type-  {-  };+  char has_iterator_helper(T*, typename T::iterator* = 0); -  struct default_connect_condition+  template <typename T>+  struct has_iterator_typedef   {-    template <typename Endpoint>-    bool operator()(const asio::error_code&, const Endpoint&)-    {-      return true;-    }+    enum { value = (sizeof((has_iterator_helper)((T*)(0))) == 1) };   }; } // namespace detail -#if defined(GENERATING_DOCUMENTATION)- /// Type trait used to determine whether a type is an endpoint sequence that can /// be used with with @c connect and @c async_connect. template <typename T> struct is_endpoint_sequence {+#if defined(GENERATING_DOCUMENTATION)   /// The value member is true if the type may be used as an endpoint sequence.-  static const bool value = automatically_determined;-};--/// Trait for determining whether a function object is a connect condition that-/// can be used with @c connect and @c async_connect.-template <typename T, typename Iterator>-struct is_connect_condition-{-  /// The value member is true if the type may be used as a connect condition.-  static constexpr bool value = automatically_determined;-};--#else // defined(GENERATING_DOCUMENTATION)--template <typename T>-struct is_endpoint_sequence : detail::is_endpoint_sequence_helper<T>-{-};--template <typename T, typename Iterator>-struct is_connect_condition : detail::is_connect_condition_helper<T, Iterator>-{+  static const bool value;+#else+  enum+  {+    value = detail::has_iterator_typedef<T>::value+  };+#endif }; -#endif // defined(GENERATING_DOCUMENTATION)- /**  * @defgroup connect asio::connect  *@@ -157,9 +94,8 @@ template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints,-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    > = 0);+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type = 0);  /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -194,10 +130,68 @@ template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints, asio::error_code& ec,-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    > = 0);+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type = 0); +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use range overload.) Establishes a socket connection by trying+/// each endpoint in a sequence.+/**+ * This function attempts to connect a socket to one of a sequence of+ * endpoints. It does this by repeated calls to the socket's @c connect member+ * function, once for each endpoint in the sequence, until a connection is+ * successfully established.+ *+ * @param s The socket to be connected. If the socket is already open, it will+ * be closed.+ *+ * @param begin An iterator pointing to the start of a sequence of endpoints.+ *+ * @returns On success, an iterator denoting the successfully connected+ * endpoint. Otherwise, the end iterator.+ *+ * @throws asio::system_error Thrown on failure. If the sequence is+ * empty, the associated @c error_code is asio::error::not_found.+ * Otherwise, contains the error from the last connection attempt.+ *+ * @note This overload assumes that a default constructed object of type @c+ * Iterator represents the end of the sequence. This is a valid assumption for+ * iterator types such as @c asio::ip::tcp::resolver::iterator.+ */+template <typename Protocol, typename Executor, typename Iterator>+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);++/// (Deprecated: Use range overload.) Establishes a socket connection by trying+/// each endpoint in a sequence.+/**+ * This function attempts to connect a socket to one of a sequence of+ * endpoints. It does this by repeated calls to the socket's @c connect member+ * function, once for each endpoint in the sequence, until a connection is+ * successfully established.+ *+ * @param s The socket to be connected. If the socket is already open, it will+ * be closed.+ *+ * @param begin An iterator pointing to the start of a sequence of endpoints.+ *+ * @param ec Set to indicate what error occurred, if any. If the sequence is+ * empty, set to asio::error::not_found. Otherwise, contains the error+ * from the last connection attempt.+ *+ * @returns On success, an iterator denoting the successfully connected+ * endpoint. Otherwise, the end iterator.+ *+ * @note This overload assumes that a default constructed object of type @c+ * Iterator represents the end of the sequence. This is a valid assumption for+ * iterator types such as @c asio::ip::tcp::resolver::iterator.+ */+template <typename Protocol, typename Executor, typename Iterator>+Iterator connect(basic_socket<Protocol, Executor>& s,+    Iterator begin, asio::error_code& ec,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Establishes a socket connection by trying each endpoint in a sequence. /**  * This function attempts to connect a socket to one of a sequence of@@ -321,13 +315,8 @@     typename EndpointSequence, typename ConnectCondition> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints, ConnectCondition connect_condition,-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    > = 0,-    constraint_t<-      is_connect_condition<ConnectCondition,-        decltype(declval<const EndpointSequence&>().begin())>::value-    > = 0);+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type = 0);  /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -394,14 +383,93 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints, ConnectCondition connect_condition,     asio::error_code& ec,-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    > = 0,-    constraint_t<-      is_connect_condition<ConnectCondition,-        decltype(declval<const EndpointSequence&>().begin())>::value-    > = 0);+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type = 0); +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use range overload.) Establishes a socket connection by trying+/// each endpoint in a sequence.+/**+ * This function attempts to connect a socket to one of a sequence of+ * endpoints. It does this by repeated calls to the socket's @c connect member+ * function, once for each endpoint in the sequence, until a connection is+ * successfully established.+ *+ * @param s The socket to be connected. If the socket is already open, it will+ * be closed.+ *+ * @param begin An iterator pointing to the start of a sequence of endpoints.+ *+ * @param connect_condition A function object that is called prior to each+ * connection attempt. The signature of the function object must be:+ * @code bool connect_condition(+ *     const asio::error_code& ec,+ *     const typename Protocol::endpoint& next); @endcode+ * The @c ec parameter contains the result from the most recent connect+ * operation. Before the first connection attempt, @c ec is always set to+ * indicate success. The @c next parameter is the next endpoint to be tried.+ * The function object should return true if the next endpoint should be tried,+ * and false if it should be skipped.+ *+ * @returns On success, an iterator denoting the successfully connected+ * endpoint. Otherwise, the end iterator.+ *+ * @throws asio::system_error Thrown on failure. If the sequence is+ * empty, the associated @c error_code is asio::error::not_found.+ * Otherwise, contains the error from the last connection attempt.+ *+ * @note This overload assumes that a default constructed object of type @c+ * Iterator represents the end of the sequence. This is a valid assumption for+ * iterator types such as @c asio::ip::tcp::resolver::iterator.+ */+template <typename Protocol, typename Executor,+    typename Iterator, typename ConnectCondition>+Iterator connect(basic_socket<Protocol, Executor>& s,+    Iterator begin, ConnectCondition connect_condition,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);++/// (Deprecated: Use range overload.) Establishes a socket connection by trying+/// each endpoint in a sequence.+/**+ * This function attempts to connect a socket to one of a sequence of+ * endpoints. It does this by repeated calls to the socket's @c connect member+ * function, once for each endpoint in the sequence, until a connection is+ * successfully established.+ *+ * @param s The socket to be connected. If the socket is already open, it will+ * be closed.+ *+ * @param begin An iterator pointing to the start of a sequence of endpoints.+ *+ * @param connect_condition A function object that is called prior to each+ * connection attempt. The signature of the function object must be:+ * @code bool connect_condition(+ *     const asio::error_code& ec,+ *     const typename Protocol::endpoint& next); @endcode+ * The @c ec parameter contains the result from the most recent connect+ * operation. Before the first connection attempt, @c ec is always set to+ * indicate success. The @c next parameter is the next endpoint to be tried.+ * The function object should return true if the next endpoint should be tried,+ * and false if it should be skipped.+ *+ * @param ec Set to indicate what error occurred, if any. If the sequence is+ * empty, set to asio::error::not_found. Otherwise, contains the error+ * from the last connection attempt.+ *+ * @returns On success, an iterator denoting the successfully connected+ * endpoint. Otherwise, the end iterator.+ *+ * @note This overload assumes that a default constructed object of type @c+ * Iterator represents the end of the sequence. This is a valid assumption for+ * iterator types such as @c asio::ip::tcp::resolver::iterator.+ */+template <typename Protocol, typename Executor,+    typename Iterator, typename ConnectCondition>+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,+    ConnectCondition connect_condition, asio::error_code& ec,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0);+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Establishes a socket connection by trying each endpoint in a sequence. /**  * This function attempts to connect a socket to one of a sequence of@@ -459,10 +527,7 @@ template <typename Protocol, typename Executor,     typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,-    Iterator end, ConnectCondition connect_condition,-    constraint_t<-      is_connect_condition<ConnectCondition, Iterator>::value-    > = 0);+    Iterator end, ConnectCondition connect_condition);  /// Establishes a socket connection by trying each endpoint in a sequence. /**@@ -531,10 +596,7 @@     typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s,     Iterator begin, Iterator end, ConnectCondition connect_condition,-    asio::error_code& ec,-    constraint_t<-      is_connect_condition<ConnectCondition, Iterator>::value-    > = 0);+    asio::error_code& ec);  /*@}*/ @@ -578,7 +640,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, typename Protocol::endpoint) @endcode@@ -626,29 +688,91 @@ template <typename Protocol, typename Executor, typename EndpointSequence,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       typename Protocol::endpoint)) RangeConnectToken-        = default_completion_token_t<Executor>>-inline auto async_connect(basic_socket<Protocol, Executor>& s,+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,+    void (asio::error_code, typename Protocol::endpoint))+async_connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints,-    RangeConnectToken&& token = default_completion_token_t<Executor>(),-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    > = 0,-    constraint_t<-      !is_connect_condition<RangeConnectToken,-        decltype(declval<const EndpointSequence&>().begin())>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(RangeConnectToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<RangeConnectToken,       void (asio::error_code, typename Protocol::endpoint)>(-        declval<detail::initiate_async_range_connect<Protocol, Executor>>(),-        token, endpoints, declval<detail::default_connect_condition>()))-{-  return async_initiate<RangeConnectToken,-    void (asio::error_code, typename Protocol::endpoint)>(-      detail::initiate_async_range_connect<Protocol, Executor>(s),-      token, endpoints, detail::default_connect_condition());-}+        declval<detail::initiate_async_range_connect<Protocol, Executor> >(),+        token, endpoints, declval<detail::default_connect_condition>()))); +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use range overload.) Asynchronously establishes a socket+/// connection by trying each endpoint in a sequence.+/**+ * This function attempts to connect a socket to one of a sequence of+ * endpoints. It does this by repeated calls to the socket's @c async_connect+ * member function, once for each endpoint in the sequence, until a connection+ * is successfully established. It is an initiating function for an @ref+ * asynchronous_operation, and always returns immediately.+ *+ * @param s The socket to be connected. If the socket is already open, it will+ * be closed.+ *+ * @param begin An iterator pointing to the start of a sequence of endpoints.+ *+ * @param token The @ref completion_token that will be used to produce a+ * completion handler, which will be called when the connect completes.+ * Potential completion tokens include @ref use_future, @ref use_awaitable,+ * @ref yield_context, or a function object with the correct completion+ * signature. The function signature of the completion handler must be:+ * @code void handler(+ *   // Result of operation. if the sequence is empty, set to+ *   // asio::error::not_found. Otherwise, contains the+ *   // error from the last connection attempt.+ *   const asio::error_code& error,+ *+ *   // On success, an iterator denoting the successfully+ *   // connected endpoint. Otherwise, the end iterator.+ *   Iterator iterator+ * ); @endcode+ * Regardless of whether the asynchronous operation completes immediately or+ * not, the completion handler will not be invoked from within this function.+ * On immediate completion, invocation of the handler will be performed in a+ * manner equivalent to using asio::post().+ *+ * @par Completion Signature+ * @code void(asio::error_code, Iterator) @endcode+ *+ * @note This overload assumes that a default constructed object of type @c+ * Iterator represents the end of the sequence. This is a valid assumption for+ * iterator types such as @c asio::ip::tcp::resolver::iterator.+ *+ * @par Per-Operation Cancellation+ * This asynchronous operation supports cancellation for the following+ * asio::cancellation_type values:+ *+ * @li @c cancellation_type::terminal+ *+ * @li @c cancellation_type::partial+ *+ * if they are also supported by the socket's @c async_connect operation.+ */+template <typename Protocol, typename Executor, typename Iterator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      Iterator)) IteratorConnectToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+    void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+    ASIO_MOVE_ARG(IteratorConnectToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<IteratorConnectToken,+      void (asio::error_code, Iterator)>(+        declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+        token, begin, Iterator(),+        declval<detail::default_connect_condition>())));+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence. /**@@ -683,7 +807,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, Iterator) @endcode@@ -716,24 +840,18 @@  */ template <typename Protocol, typename Executor, typename Iterator,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>-inline auto async_connect(-    basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,-    IteratorConnectToken&& token = default_completion_token_t<Executor>(),-    constraint_t<-      !is_connect_condition<IteratorConnectToken, Iterator>::value-    > = 0)-  -> decltype(+      Iterator)) IteratorConnectToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+    void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,+    ASIO_MOVE_ARG(IteratorConnectToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<IteratorConnectToken,       void (asio::error_code, Iterator)>(-        declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),-        token, begin, end, declval<detail::default_connect_condition>()))-{-  return async_initiate<IteratorConnectToken,-    void (asio::error_code, Iterator)>(-      detail::initiate_async_iterator_connect<Protocol, Executor>(s),-      token, begin, end, detail::default_connect_condition());-}+        declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+        token, begin, end, declval<detail::default_connect_condition>())));  /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence.@@ -778,7 +896,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, typename Protocol::endpoint) @endcode@@ -850,29 +968,103 @@     typename EndpointSequence, typename ConnectCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       typename Protocol::endpoint)) RangeConnectToken-        = default_completion_token_t<Executor>>-inline auto async_connect(basic_socket<Protocol, Executor>& s,+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,+    void (asio::error_code, typename Protocol::endpoint))+async_connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints, ConnectCondition connect_condition,-    RangeConnectToken&& token = default_completion_token_t<Executor>(),-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    > = 0,-    constraint_t<-      is_connect_condition<ConnectCondition,-        decltype(declval<const EndpointSequence&>().begin())>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(RangeConnectToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<RangeConnectToken,       void (asio::error_code, typename Protocol::endpoint)>(-        declval<detail::initiate_async_range_connect<Protocol, Executor>>(),-        token, endpoints, connect_condition))-{-  return async_initiate<RangeConnectToken,-    void (asio::error_code, typename Protocol::endpoint)>(-      detail::initiate_async_range_connect<Protocol, Executor>(s),-      token, endpoints, connect_condition);-}+        declval<detail::initiate_async_range_connect<Protocol, Executor> >(),+        token, endpoints, connect_condition))); +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use range overload.) Asynchronously establishes a socket+/// connection by trying each endpoint in a sequence.+/**+ * This function attempts to connect a socket to one of a sequence of+ * endpoints. It does this by repeated calls to the socket's @c async_connect+ * member function, once for each endpoint in the sequence, until a connection+ * is successfully established. It is an initiating function for an @ref+ * asynchronous_operation, and always returns immediately.+ *+ * @param s The socket to be connected. If the socket is already open, it will+ * be closed.+ *+ * @param begin An iterator pointing to the start of a sequence of endpoints.+ *+ * @param connect_condition A function object that is called prior to each+ * connection attempt. The signature of the function object must be:+ * @code bool connect_condition(+ *     const asio::error_code& ec,+ *     const typename Protocol::endpoint& next); @endcode+ * The @c ec parameter contains the result from the most recent connect+ * operation. Before the first connection attempt, @c ec is always set to+ * indicate success. The @c next parameter is the next endpoint to be tried.+ * The function object should return true if the next endpoint should be tried,+ * and false if it should be skipped.+ *+ * @param token The @ref completion_token that will be used to produce a+ * completion handler, which will be called when the connect completes.+ * Potential completion tokens include @ref use_future, @ref use_awaitable,+ * @ref yield_context, or a function object with the correct completion+ * signature. The function signature of the completion handler must be:+ * @code void handler(+ *   // Result of operation. if the sequence is empty, set to+ *   // asio::error::not_found. Otherwise, contains the+ *   // error from the last connection attempt.+ *   const asio::error_code& error,+ *+ *   // On success, an iterator denoting the successfully+ *   // connected endpoint. Otherwise, the end iterator.+ *   Iterator iterator+ * ); @endcode+ * Regardless of whether the asynchronous operation completes immediately or+ * not, the completion handler will not be invoked from within this function.+ * On immediate completion, invocation of the handler will be performed in a+ * manner equivalent to using asio::post().+ *+ * @par Completion Signature+ * @code void(asio::error_code, Iterator) @endcode+ *+ * @note This overload assumes that a default constructed object of type @c+ * Iterator represents the end of the sequence. This is a valid assumption for+ * iterator types such as @c asio::ip::tcp::resolver::iterator.+ *+ * @par Per-Operation Cancellation+ * This asynchronous operation supports cancellation for the following+ * asio::cancellation_type values:+ *+ * @li @c cancellation_type::terminal+ *+ * @li @c cancellation_type::partial+ *+ * if they are also supported by the socket's @c async_connect operation.+ */+template <typename Protocol, typename Executor,+    typename Iterator, typename ConnectCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      Iterator)) IteratorConnectToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+    void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+    ConnectCondition connect_condition,+    ASIO_MOVE_ARG(IteratorConnectToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<IteratorConnectToken,+      void (asio::error_code, Iterator)>(+        declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+        token, begin, Iterator(), connect_condition)));+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Asynchronously establishes a socket connection by trying each endpoint in a /// sequence. /**@@ -918,7 +1110,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, Iterator) @endcode@@ -990,24 +1182,19 @@ template <typename Protocol, typename Executor,     typename Iterator, typename ConnectCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      Iterator)) IteratorConnectToken = default_completion_token_t<Executor>>-inline auto async_connect(basic_socket<Protocol, Executor>& s,-    Iterator begin, Iterator end, ConnectCondition connect_condition,-    IteratorConnectToken&& token = default_completion_token_t<Executor>(),-    constraint_t<-      is_connect_condition<ConnectCondition, Iterator>::value-    > = 0)-  -> decltype(+      Iterator)) IteratorConnectToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+    void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+    Iterator end, ConnectCondition connect_condition,+    ASIO_MOVE_ARG(IteratorConnectToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<IteratorConnectToken,       void (asio::error_code, Iterator)>(-        declval<detail::initiate_async_iterator_connect<Protocol, Executor>>(),-        token, begin, end, connect_condition))-{-  return async_initiate<IteratorConnectToken,-    void (asio::error_code, Iterator)>(-      detail::initiate_async_iterator_connect<Protocol, Executor>(s),-      token, begin, end, connect_condition);-}+        declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+        token, begin, end, connect_condition)));  /*@}*/ @@ -1017,4 +1204,4 @@  #include "asio/impl/connect.hpp" -#endif // ASIO_CONNECT_HPP+#endif
link/modules/asio-standalone/asio/include/asio/connect_pipe.hpp view
@@ -2,7 +2,7 @@ // connect_pipe.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/consign.hpp view
@@ -1,8 +1,8 @@ // // consign.hpp-// ~~~~~~~~~~~+// ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+    && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+  || defined(GENERATING_DOCUMENTATION)+ #include <tuple> #include "asio/detail/type_traits.hpp" @@ -36,9 +41,11 @@ public:   /// Constructor.   template <typename T, typename... V>-  constexpr explicit consign_t(T&& completion_token, V&&... values)-    : token_(static_cast<T&&>(completion_token)),-      values_(static_cast<V&&>(values)...)+  ASIO_CONSTEXPR explicit consign_t(+      ASIO_MOVE_ARG(T) completion_token,+      ASIO_MOVE_ARG(V)... values)+    : token_(ASIO_MOVE_CAST(T)(completion_token)),+      values_(ASIO_MOVE_CAST(V)(values)...)   {   } @@ -57,13 +64,15 @@  * called.  */ template <typename CompletionToken, typename... Values>-ASIO_NODISCARD inline constexpr-consign_t<decay_t<CompletionToken>, decay_t<Values>...>-consign(CompletionToken&& completion_token, Values&&... values)+ASIO_NODISCARD inline ASIO_CONSTEXPR consign_t<+  typename decay<CompletionToken>::type, typename decay<Values>::type...>+consign(ASIO_MOVE_ARG(CompletionToken) completion_token,+    ASIO_MOVE_ARG(Values)... values) {-  return consign_t<decay_t<CompletionToken>, decay_t<Values>...>(-      static_cast<CompletionToken&&>(completion_token),-      static_cast<Values&&>(values)...);+  return consign_t<+    typename decay<CompletionToken>::type, typename decay<Values>::type...>(+      ASIO_MOVE_CAST(CompletionToken)(completion_token),+      ASIO_MOVE_CAST(Values)(values)...); }  } // namespace asio@@ -71,5 +80,9 @@ #include "asio/detail/pop_options.hpp"  #include "asio/impl/consign.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+       //     && defined(ASIO_HAS_VARIADIC_TEMPLATES))+       //   || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_CONSIGN_HPP
link/modules/asio-standalone/asio/include/asio/coroutine.hpp view
@@ -2,7 +2,7 @@ // coroutine.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -111,7 +111,7 @@  *  * @code yield  * {- *   mutable_buffer b = buffer(*buffer_);+ *   mutable_buffers_1 b = buffer(*buffer_);  *   socket_->async_read_some(b, *this);  * } @endcode  *@@ -200,7 +200,7 @@  * The @c fork pseudo-keyword is used when "forking" a coroutine, i.e. splitting  * it into two (or more) copies. One use of @c fork is in a server, where a new  * coroutine is created to handle each client connection:- *+ *   * @code reenter (this)  * {  *   do@@ -211,9 +211,9 @@  *   } while (is_parent());  *   ... client-specific handling follows ...  * } @endcode- *+ *   * The logical steps involved in a @c fork are:- *+ *   * @li @c fork saves the current state of the coroutine.  * @li The statement creates a copy of the coroutine and either executes it  *     immediately or schedules it for later execution.@@ -258,6 +258,7 @@   int value_; }; + namespace detail {  class coroutine_ref@@ -265,7 +266,6 @@ public:   coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {}   coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {}-  coroutine_ref(const coroutine_ref&) = default;   ~coroutine_ref() { if (!modified_) value_ = -1; }   operator int() const { return value_; }   int& operator=(int v) { modified_ = true; return value_ = v; }
link/modules/asio-standalone/asio/include/asio/deadline_timer.hpp view
@@ -2,7 +2,7 @@ // deadline_timer.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,8 +17,6 @@  #include "asio/detail/config.hpp" -#if !defined(ASIO_NO_DEPRECATED)- #if defined(ASIO_HAS_BOOST_DATE_TIME) \   || defined(GENERATING_DOCUMENTATION) @@ -29,15 +27,12 @@  namespace asio { -/// (Deprecated: Use system_timer.) Typedef for the typical usage of timer. Uses-/// a UTC clock.+/// Typedef for the typical usage of timer. Uses a UTC clock. typedef basic_deadline_timer<boost::posix_time::ptime> deadline_timer;  } // namespace asio  #endif // defined(ASIO_HAS_BOOST_DATE_TIME)        // || defined(GENERATING_DOCUMENTATION)--#endif // !defined(ASIO_NO_DEPRECATED)  #endif // ASIO_DEADLINE_TIMER_HPP
− link/modules/asio-standalone/asio/include/asio/default_completion_token.hpp
@@ -1,89 +0,0 @@-//-// default_completion_token.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DEFAULT_COMPLETION_TOKEN_HPP-#define ASIO_DEFAULT_COMPLETION_TOKEN_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--class deferred_t;--namespace detail {--template <typename T, typename = void>-struct default_completion_token_impl-{-  typedef deferred_t type;-};--template <typename T>-struct default_completion_token_impl<T,-    void_t<typename T::default_completion_token_type>-  >-{-  typedef typename T::default_completion_token_type type;-};--} // namespace detail--#if defined(GENERATING_DOCUMENTATION)--/// Traits type used to determine the default completion token type associated-/// with a type (such as an executor).-/**- * A program may specialise this traits type if the @c T template parameter in- * the specialisation is a user-defined type.- *- * Specialisations of this trait may provide a nested typedef @c type, which is- * a default-constructible completion token type.- *- * If not otherwise specialised, the default completion token type is- * asio::deferred_t.- */-template <typename T>-struct default_completion_token-{-  /// If @c T has a nested type @c default_completion_token_type,-  /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type-  /// is asio::deferred_t.-  typedef see_below type;-};-#else-template <typename T>-struct default_completion_token-  : detail::default_completion_token_impl<T>-{-};-#endif--template <typename T>-using default_completion_token_t = typename default_completion_token<T>::type;--#define ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \-  = typename ::asio::default_completion_token<e>::type-#define ASIO_DEFAULT_COMPLETION_TOKEN(e) \-  = typename ::asio::default_completion_token<e>::type()--} // namespace asio--#include "asio/detail/pop_options.hpp"--#include "asio/deferred.hpp"--#endif // ASIO_DEFAULT_COMPLETION_TOKEN_HPP
link/modules/asio-standalone/asio/include/asio/defer.hpp view
@@ -2,7 +2,7 @@ // defer.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -79,10 +79,11 @@  * @code void() @endcode  */ template <ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>-auto defer(NullaryToken&& token)-  -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) defer(+    ASIO_MOVE_ARG(NullaryToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<NullaryToken, void()>(-      declval<detail::initiate_defer>(), token))+        declval<detail::initiate_defer>(), token))) {   return async_initiate<NullaryToken, void()>(       detail::initiate_defer(), token);@@ -161,18 +162,19 @@  */ template <typename Executor,     ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken-      = default_completion_token_t<Executor>>-auto defer(const Executor& ex,-    NullaryToken&& token-      = default_completion_token_t<Executor>(),-    constraint_t<+      ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) defer(+    const Executor& ex,+    ASIO_MOVE_ARG(NullaryToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+    typename constraint<       (execution::is_executor<Executor>::value           && can_require<Executor, execution::blocking_t::never_t>::value)         || is_executor<Executor>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<NullaryToken, void()>(-      declval<detail::initiate_defer_with_executor<Executor>>(), token))+        declval<detail::initiate_defer_with_executor<Executor> >(), token))) {   return async_initiate<NullaryToken, void()>(       detail::initiate_defer_with_executor<Executor>(ex), token);@@ -193,17 +195,19 @@  */ template <typename ExecutionContext,     ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken-      = default_completion_token_t<typename ExecutionContext::executor_type>>-auto defer(ExecutionContext& ctx,-    NullaryToken&& token-      = default_completion_token_t<typename ExecutionContext::executor_type>(),-    constraint_t<-      is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)-  -> decltype(+      ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+        typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) defer(+    ExecutionContext& ctx,+    ASIO_MOVE_ARG(NullaryToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename ExecutionContext::executor_type),+    typename constraint<is_convertible<+      ExecutionContext&, execution_context&>::value>::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<NullaryToken, void()>(-      declval<detail::initiate_defer_with_executor<-        typename ExecutionContext::executor_type>>(), token))+        declval<detail::initiate_defer_with_executor<+          typename ExecutionContext::executor_type> >(), token))) {   return async_initiate<NullaryToken, void()>(       detail::initiate_defer_with_executor<
link/modules/asio-standalone/asio/include/asio/deferred.hpp view
@@ -2,7 +2,7 @@ // deferred.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,12 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+    && defined(ASIO_HAS_DECLTYPE) \+    && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+  || defined(GENERATING_DOCUMENTATION)+ #include <tuple> #include "asio/associator.hpp" #include "asio/async_result.hpp"@@ -61,18 +67,19 @@ { public:   template <typename H, typename T>-  explicit deferred_sequence_handler(H&& handler, T&& tail)-    : handler_(static_cast<H&&>(handler)),-      tail_(static_cast<T&&>(tail))+  explicit deferred_sequence_handler(+      ASIO_MOVE_ARG(H) handler, ASIO_MOVE_ARG(T) tail)+    : handler_(ASIO_MOVE_CAST(H)(handler)),+      tail_(ASIO_MOVE_CAST(T)(tail))   {   }    template <typename... Args>-  void operator()(Args&&... args)+  void operator()(ASIO_MOVE_ARG(Args)... args)   {-    static_cast<Tail&&>(tail_)(-        static_cast<Args&&>(args)...)(-          static_cast<Handler&&>(handler_));+    ASIO_MOVE_OR_LVALUE(Tail)(tail_)(+        ASIO_MOVE_CAST(Args)(args)...)(+          ASIO_MOVE_OR_LVALUE(Handler)(handler_));   }  //private:@@ -87,11 +94,15 @@   struct initiate   {     template <typename Handler>-    void operator()(Handler&& handler, Head head, Tail&& tail)+    void operator()(ASIO_MOVE_ARG(Handler) handler,+        Head head, ASIO_MOVE_ARG(Tail) tail)     {-      static_cast<Head&&>(head)(-          deferred_sequence_handler<decay_t<Handler>, decay_t<Tail>>(-            static_cast<Handler&&>(handler), static_cast<Tail&&>(tail)));+      ASIO_MOVE_OR_LVALUE(Head)(head)(+          deferred_sequence_handler<+            typename decay<Handler>::type,+            typename decay<Tail>::type>(+              ASIO_MOVE_CAST(Handler)(handler),+              ASIO_MOVE_CAST(Tail)(tail)));     }   }; @@ -100,32 +111,40 @@  public:   template <typename H, typename T>-  constexpr explicit deferred_sequence_base(H&& head, T&& tail)-    : head_(static_cast<H&&>(head)),-      tail_(static_cast<T&&>(tail))+  ASIO_CONSTEXPR explicit deferred_sequence_base(+      ASIO_MOVE_ARG(H) head, ASIO_MOVE_ARG(T) tail)+    : head_(ASIO_MOVE_CAST(H)(head)),+      tail_(ASIO_MOVE_CAST(T)(tail))   {   }    template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>-  auto operator()(CompletionToken&& token) &&+  auto operator()(+      ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL     -> decltype(-      async_initiate<CompletionToken, Signatures...>(-        initiate(), token, static_cast<Head&&>(this->head_),-        static_cast<Tail&&>(this->tail_)))+        asio::async_initiate<CompletionToken, Signatures...>(+          declval<initiate>(), token,+          ASIO_MOVE_OR_LVALUE(Head)(this->head_),+          ASIO_MOVE_OR_LVALUE(Tail)(this->tail_)))   {-    return async_initiate<CompletionToken, Signatures...>(initiate(),-        token, static_cast<Head&&>(head_), static_cast<Tail&&>(tail_));+    return asio::async_initiate<CompletionToken, Signatures...>(+        initiate(), token,+        ASIO_MOVE_OR_LVALUE(Head)(head_),+        ASIO_MOVE_OR_LVALUE(Tail)(tail_));   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>-  auto operator()(CompletionToken&& token) const &+  auto operator()(+      ASIO_MOVE_ARG(CompletionToken) token) const &     -> decltype(-      async_initiate<CompletionToken, Signatures...>(-        initiate(), token, this->head_, this->tail_))+        asio::async_initiate<CompletionToken, Signatures...>(+          initiate(), token, this->head_, this->tail_))   {-    return async_initiate<CompletionToken, Signatures...>(+    return asio::async_initiate<CompletionToken, Signatures...>(         initiate(), token, head_, tail_);   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) };  // Two-step application of variadic Signatures to determine correct base type.@@ -157,15 +176,17 @@ {   /// No effect.   template <typename... Args>-  void operator()(Args&&...) &&+  void operator()(ASIO_MOVE_ARG(Args)...) ASIO_RVALUE_REF_QUAL   {   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   /// No effect.   template <typename... Args>-  void operator()(Args&&...) const &+  void operator()(ASIO_MOVE_ARG(Args)...) const &   {   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) };  #if !defined(GENERATING_DOCUMENTATION)@@ -184,10 +205,11 @@ class deferred_function { public:-  /// Constructor.+  /// Constructor.    template <typename F>-  constexpr explicit deferred_function(deferred_init_tag, F&& function)-    : function_(static_cast<F&&>(function))+  ASIO_CONSTEXPR explicit deferred_function(+      deferred_init_tag, ASIO_MOVE_ARG(F) function)+    : function_(ASIO_MOVE_CAST(F)(function))   {   } @@ -196,24 +218,30 @@  public:   template <typename... Args>-  auto operator()(Args&&... args) &&+  auto operator()(+      ASIO_MOVE_ARG(Args)... args) ASIO_RVALUE_REF_QUAL     -> decltype(-      static_cast<Function&&>(this->function_)(static_cast<Args&&>(args)...))+        ASIO_MOVE_CAST(Function)(this->function_)(+          ASIO_MOVE_CAST(Args)(args)...))   {-    return static_cast<Function&&>(function_)(static_cast<Args&&>(args)...);+    return ASIO_MOVE_CAST(Function)(function_)(+        ASIO_MOVE_CAST(Args)(args)...);   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   template <typename... Args>-  auto operator()(Args&&... args) const &-    -> decltype(Function(function_)(static_cast<Args&&>(args)...))+  auto operator()(+      ASIO_MOVE_ARG(Args)... args) const &+    -> decltype(Function(function_)(ASIO_MOVE_CAST(Args)(args)...))   {-    return Function(function_)(static_cast<Args&&>(args)...);+    return Function(function_)(ASIO_MOVE_CAST(Args)(args)...);   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) };  #if !defined(GENERATING_DOCUMENTATION) template <typename Function>-struct is_deferred<deferred_function<Function>> : true_type+struct is_deferred<deferred_function<Function> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION)@@ -228,72 +256,85 @@   struct initiate   {     template <typename Handler, typename... V>-    void operator()(Handler handler, V&&... values)+    void operator()(Handler handler, ASIO_MOVE_ARG(V)... values)     {-      static_cast<Handler&&>(handler)(static_cast<V&&>(values)...);+      ASIO_MOVE_OR_LVALUE(Handler)(handler)(+          ASIO_MOVE_CAST(V)(values)...);     }   };    template <typename CompletionToken, std::size_t... I>-  auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)+  auto invoke_helper(+      ASIO_MOVE_ARG(CompletionToken) token,+      detail::index_sequence<I...>)     -> decltype(-      async_initiate<CompletionToken, void(Values...)>(initiate(), token,-        std::get<I>(static_cast<std::tuple<Values...>&&>(this->values_))...))+        asio::async_initiate<CompletionToken, void(Values...)>(+          initiate(), token,+          std::get<I>(+            ASIO_MOVE_CAST(std::tuple<Values...>)(this->values_))...))   {-    return async_initiate<CompletionToken, void(Values...)>(initiate(), token,-        std::get<I>(static_cast<std::tuple<Values...>&&>(values_))...);+    return asio::async_initiate<CompletionToken, void(Values...)>(+        initiate(), token,+        std::get<I>(ASIO_MOVE_CAST(std::tuple<Values...>)(values_))...);   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   template <typename CompletionToken, std::size_t... I>-  auto const_invoke_helper(CompletionToken&& token,+  auto const_invoke_helper(+      ASIO_MOVE_ARG(CompletionToken) token,       detail::index_sequence<I...>)     -> decltype(-      async_initiate<CompletionToken, void(Values...)>(-        initiate(), token, std::get<I>(values_)...))+        asio::async_initiate<CompletionToken, void(Values...)>(+          initiate(), token, std::get<I>(values_)...))   {-    return async_initiate<CompletionToken, void(Values...)>(+    return asio::async_initiate<CompletionToken, void(Values...)>(         initiate(), token, std::get<I>(values_)...);   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)  public:   /// Construct a deferred asynchronous operation from the arguments to an   /// initiation function object.   template <typename... V>-  constexpr explicit deferred_values(-      deferred_init_tag, V&&... values)-    : values_(static_cast<V&&>(values)...)+  ASIO_CONSTEXPR explicit deferred_values(+      deferred_init_tag, ASIO_MOVE_ARG(V)... values)+    : values_(ASIO_MOVE_CAST(V)(values)...)   {   }    /// Initiate the deferred operation using the supplied completion token.   template <ASIO_COMPLETION_TOKEN_FOR(void(Values...)) CompletionToken>-  auto operator()(CompletionToken&& token) &&+  auto operator()(+      ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL     -> decltype(-      this->invoke_helper(-        static_cast<CompletionToken&&>(token),-        detail::index_sequence_for<Values...>()))+        this->invoke_helper(+          ASIO_MOVE_CAST(CompletionToken)(token),+          detail::index_sequence_for<Values...>()))   {     return this->invoke_helper(-        static_cast<CompletionToken&&>(token),+        ASIO_MOVE_CAST(CompletionToken)(token),         detail::index_sequence_for<Values...>());   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   template <ASIO_COMPLETION_TOKEN_FOR(void(Values...)) CompletionToken>-  auto operator()(CompletionToken&& token) const &+  auto operator()(+      ASIO_MOVE_ARG(CompletionToken) token) const &     -> decltype(-      this->const_invoke_helper(-        static_cast<CompletionToken&&>(token),-        detail::index_sequence_for<Values...>()))+        this->const_invoke_helper(+          ASIO_MOVE_CAST(CompletionToken)(token),+          detail::index_sequence_for<Values...>()))   {     return this->const_invoke_helper(-        static_cast<CompletionToken&&>(token),+        ASIO_MOVE_CAST(CompletionToken)(token),         detail::index_sequence_for<Values...>());   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) };  #if !defined(GENERATING_DOCUMENTATION) template <typename... Values>-struct is_deferred<deferred_values<Values...>> : true_type+struct is_deferred<deferred_values<Values...> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION)@@ -303,70 +344,79 @@ class ASIO_NODISCARD deferred_async_operation { private:-  typedef decay_t<Initiation> initiation_t;+  typedef typename decay<Initiation>::type initiation_t;   initiation_t initiation_;-  typedef std::tuple<decay_t<InitArgs>...> init_args_t;+  typedef std::tuple<typename decay<InitArgs>::type...> init_args_t;   init_args_t init_args_;    template <typename CompletionToken, std::size_t... I>-  auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)+  auto invoke_helper(+      ASIO_MOVE_ARG(CompletionToken) token,+      detail::index_sequence<I...>)     -> decltype(-      async_initiate<CompletionToken, Signature>(-        static_cast<initiation_t&&>(initiation_), token,-        std::get<I>(static_cast<init_args_t&&>(init_args_))...))+        asio::async_initiate<CompletionToken, Signature>(+          ASIO_MOVE_CAST(initiation_t)(initiation_), token,+          std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...))   {-    return async_initiate<CompletionToken, Signature>(-        static_cast<initiation_t&&>(initiation_), token,-        std::get<I>(static_cast<init_args_t&&>(init_args_))...);+    return asio::async_initiate<CompletionToken, Signature>(+        ASIO_MOVE_CAST(initiation_t)(initiation_), token,+        std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...);   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   template <typename CompletionToken, std::size_t... I>-  auto const_invoke_helper(CompletionToken&& token,+  auto const_invoke_helper(+      ASIO_MOVE_ARG(CompletionToken) token,       detail::index_sequence<I...>) const &     -> decltype(-      async_initiate<CompletionToken, Signature>(-        conditional_t<true, initiation_t, CompletionToken>(initiation_),-        token, std::get<I>(init_args_)...))-  {-    return async_initiate<CompletionToken, Signature>(+        asio::async_initiate<CompletionToken, Signature>(+          initiation_t(initiation_), token, std::get<I>(init_args_)...))+    {+    return asio::async_initiate<CompletionToken, Signature>(         initiation_t(initiation_), token, std::get<I>(init_args_)...);   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)  public:   /// Construct a deferred asynchronous operation from the arguments to an   /// initiation function object.   template <typename I, typename... A>-  constexpr explicit deferred_async_operation(-      deferred_init_tag, I&& initiation, A&&... init_args)-    : initiation_(static_cast<I&&>(initiation)),-      init_args_(static_cast<A&&>(init_args)...)+  ASIO_CONSTEXPR explicit deferred_async_operation(+      deferred_init_tag, ASIO_MOVE_ARG(I) initiation,+      ASIO_MOVE_ARG(A)... init_args)+    : initiation_(ASIO_MOVE_CAST(I)(initiation)),+      init_args_(ASIO_MOVE_CAST(A)(init_args)...)   {   }    /// Initiate the asynchronous operation using the supplied completion token.   template <ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>-  auto operator()(CompletionToken&& token) &&+  auto operator()(+      ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL     -> decltype(-      this->invoke_helper(-        static_cast<CompletionToken&&>(token),-        detail::index_sequence_for<InitArgs...>()))+        this->invoke_helper(+          ASIO_MOVE_CAST(CompletionToken)(token),+          detail::index_sequence_for<InitArgs...>()))   {     return this->invoke_helper(-        static_cast<CompletionToken&&>(token),+        ASIO_MOVE_CAST(CompletionToken)(token),         detail::index_sequence_for<InitArgs...>());   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   template <ASIO_COMPLETION_TOKEN_FOR(Signature) CompletionToken>-  auto operator()(CompletionToken&& token) const &+  auto operator()(+      ASIO_MOVE_ARG(CompletionToken) token) const &     -> decltype(-      this->const_invoke_helper(-        static_cast<CompletionToken&&>(token),-        detail::index_sequence_for<InitArgs...>()))+        this->const_invoke_helper(+          ASIO_MOVE_CAST(CompletionToken)(token),+          detail::index_sequence_for<InitArgs...>()))   {     return this->const_invoke_helper(-        static_cast<CompletionToken&&>(token),+        ASIO_MOVE_CAST(CompletionToken)(token),         detail::index_sequence_for<InitArgs...>());   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) };  /// Encapsulates a deferred asynchronous operation thas has multiple completion@@ -376,75 +426,85 @@     deferred_signatures<Signatures...>, Initiation, InitArgs...> { private:-  typedef decay_t<Initiation> initiation_t;+  typedef typename decay<Initiation>::type initiation_t;   initiation_t initiation_;-  typedef std::tuple<decay_t<InitArgs>...> init_args_t;+  typedef std::tuple<typename decay<InitArgs>::type...> init_args_t;   init_args_t init_args_;    template <typename CompletionToken, std::size_t... I>-  auto invoke_helper(CompletionToken&& token, detail::index_sequence<I...>)+  auto invoke_helper(+      ASIO_MOVE_ARG(CompletionToken) token,+      detail::index_sequence<I...>)     -> decltype(-      async_initiate<CompletionToken, Signatures...>(-        static_cast<initiation_t&&>(initiation_), token,-        std::get<I>(static_cast<init_args_t&&>(init_args_))...))+        asio::async_initiate<CompletionToken, Signatures...>(+          ASIO_MOVE_CAST(initiation_t)(initiation_), token,+          std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...))   {-    return async_initiate<CompletionToken, Signatures...>(-        static_cast<initiation_t&&>(initiation_), token,-        std::get<I>(static_cast<init_args_t&&>(init_args_))...);+    return asio::async_initiate<CompletionToken, Signatures...>(+        ASIO_MOVE_CAST(initiation_t)(initiation_), token,+        std::get<I>(ASIO_MOVE_CAST(init_args_t)(init_args_))...);   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   template <typename CompletionToken, std::size_t... I>-  auto const_invoke_helper(CompletionToken&& token,+  auto const_invoke_helper(+      ASIO_MOVE_ARG(CompletionToken) token,       detail::index_sequence<I...>) const &     -> decltype(-      async_initiate<CompletionToken, Signatures...>(-        initiation_t(initiation_), token, std::get<I>(init_args_)...))-  {-    return async_initiate<CompletionToken, Signatures...>(+        asio::async_initiate<CompletionToken, Signatures...>(+          initiation_t(initiation_), token, std::get<I>(init_args_)...))+    {+    return asio::async_initiate<CompletionToken, Signatures...>(         initiation_t(initiation_), token, std::get<I>(init_args_)...);   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)  public:   /// Construct a deferred asynchronous operation from the arguments to an   /// initiation function object.   template <typename I, typename... A>-  constexpr explicit deferred_async_operation(-      deferred_init_tag, I&& initiation, A&&... init_args)-    : initiation_(static_cast<I&&>(initiation)),-      init_args_(static_cast<A&&>(init_args)...)+  ASIO_CONSTEXPR explicit deferred_async_operation(+      deferred_init_tag, ASIO_MOVE_ARG(I) initiation,+      ASIO_MOVE_ARG(A)... init_args)+    : initiation_(ASIO_MOVE_CAST(I)(initiation)),+      init_args_(ASIO_MOVE_CAST(A)(init_args)...)   {   }    /// Initiate the asynchronous operation using the supplied completion token.   template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>-  auto operator()(CompletionToken&& token) &&+  auto operator()(+      ASIO_MOVE_ARG(CompletionToken) token) ASIO_RVALUE_REF_QUAL     -> decltype(-      this->invoke_helper(-        static_cast<CompletionToken&&>(token),-        detail::index_sequence_for<InitArgs...>()))+        this->invoke_helper(+          ASIO_MOVE_CAST(CompletionToken)(token),+          detail::index_sequence_for<InitArgs...>()))   {     return this->invoke_helper(-        static_cast<CompletionToken&&>(token),+        ASIO_MOVE_CAST(CompletionToken)(token),         detail::index_sequence_for<InitArgs...>());   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   template <ASIO_COMPLETION_TOKEN_FOR(Signatures...) CompletionToken>-  auto operator()(CompletionToken&& token) const &+  auto operator()(+      ASIO_MOVE_ARG(CompletionToken) token) const &     -> decltype(-      this->const_invoke_helper(-        static_cast<CompletionToken&&>(token),-        detail::index_sequence_for<InitArgs...>()))+        this->const_invoke_helper(+          ASIO_MOVE_CAST(CompletionToken)(token),+          detail::index_sequence_for<InitArgs...>()))   {     return this->const_invoke_helper(-        static_cast<CompletionToken&&>(token),+        ASIO_MOVE_CAST(CompletionToken)(token),         detail::index_sequence_for<InitArgs...>());   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) };  #if !defined(GENERATING_DOCUMENTATION) template <typename Signature, typename Initiation, typename... InitArgs> struct is_deferred<-    deferred_async_operation<Signature, Initiation, InitArgs...>> : true_type+    deferred_async_operation<Signature, Initiation, InitArgs...> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION)@@ -456,30 +516,33 @@ { public:   template <typename H, typename T>-  constexpr explicit deferred_sequence(deferred_init_tag, H&& head, T&& tail)+  ASIO_CONSTEXPR explicit deferred_sequence(deferred_init_tag,+      ASIO_MOVE_ARG(H) head, ASIO_MOVE_ARG(T) tail)     : detail::deferred_sequence_types<Head, Tail>::base(-        static_cast<H&&>(head), static_cast<T&&>(tail))+        ASIO_MOVE_CAST(H)(head), ASIO_MOVE_CAST(T)(tail))   {   }  #if defined(GENERATING_DOCUMENTATION)   template <typename CompletionToken>-  auto operator()(CompletionToken&& token) &&;+  auto operator()(ASIO_MOVE_ARG(CompletionToken) token)+    ASIO_RVALUE_REF_QUAL;    template <typename CompletionToken>-  auto operator()(CompletionToken&& token) const &;-#endif // defined(GENERATING_DOCUMENTATION)+  auto operator()(ASIO_MOVE_ARG(CompletionToken) token) const &;+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) };  #if !defined(GENERATING_DOCUMENTATION) template <typename Head, typename Tail>-struct is_deferred<deferred_sequence<Head, Tail>> : true_type+struct is_deferred<deferred_sequence<Head, Tail> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION)  /// Used to represent a deferred conditional branch.-template <typename OnTrue = deferred_noop, typename OnFalse = deferred_noop>+template <typename OnTrue = deferred_noop,+    typename OnFalse = deferred_noop> class ASIO_NODISCARD deferred_conditional { private:@@ -487,9 +550,10 @@    // Helper constructor.   template <typename T, typename F>-  explicit deferred_conditional(bool b, T&& on_true, F&& on_false)-    : on_true_(static_cast<T&&>(on_true)),-      on_false_(static_cast<F&&>(on_false)),+  explicit deferred_conditional(bool b, ASIO_MOVE_ARG(T) on_true,+      ASIO_MOVE_ARG(F) on_false)+    : on_true_(ASIO_MOVE_CAST(T)(on_true)),+      on_false_(ASIO_MOVE_CAST(F)(on_false)),       bool_(b)   {   }@@ -501,88 +565,94 @@ public:   /// Construct a deferred conditional with the value to determine which branch   /// will be executed.-  constexpr explicit deferred_conditional(bool b)+  ASIO_CONSTEXPR explicit deferred_conditional(bool b)     : on_true_(),       on_false_(),       bool_(b)   {   } -  /// Invoke the conditional branch bsaed on the stored value.+  /// Invoke the conditional branch bsaed on the stored alue.   template <typename... Args>-  auto operator()(Args&&... args) &&-    -> decltype(static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...))+  auto operator()(ASIO_MOVE_ARG(Args)... args) ASIO_RVALUE_REF_QUAL+    -> decltype(+        ASIO_MOVE_OR_LVALUE(OnTrue)(on_true_)(+          ASIO_MOVE_CAST(Args)(args)...))   {     if (bool_)     {-      return static_cast<OnTrue&&>(on_true_)(static_cast<Args&&>(args)...);+      return ASIO_MOVE_OR_LVALUE(OnTrue)(on_true_)(+          ASIO_MOVE_CAST(Args)(args)...);     }     else     {-      return static_cast<OnFalse&&>(on_false_)(static_cast<Args&&>(args)...);+      return ASIO_MOVE_OR_LVALUE(OnFalse)(on_false_)(+          ASIO_MOVE_CAST(Args)(args)...);     }   } +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)   template <typename... Args>-  auto operator()(Args&&... args) const &-    -> decltype(on_true_(static_cast<Args&&>(args)...))+  auto operator()(ASIO_MOVE_ARG(Args)... args) const &+    -> decltype(on_true_(ASIO_MOVE_CAST(Args)(args)...))   {     if (bool_)     {-      return on_true_(static_cast<Args&&>(args)...);+      return on_true_(ASIO_MOVE_CAST(Args)(args)...);     }     else     {-      return on_false_(static_cast<Args&&>(args)...);+      return on_false_(ASIO_MOVE_CAST(Args)(args)...);     }   }+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)    /// Set the true branch of the conditional.   template <typename T>   deferred_conditional<T, OnFalse> then(T on_true,-      constraint_t<+      typename constraint<         is_deferred<T>::value-      >* = 0,-      constraint_t<+      >::type* = 0,+      typename constraint<         is_same<-          conditional_t<true, OnTrue, T>,+          typename conditional<true, OnTrue, T>::type,           deferred_noop         >::value-      >* = 0) &&+      >::type* = 0) ASIO_RVALUE_REF_QUAL   {     return deferred_conditional<T, OnFalse>(-        bool_, static_cast<T&&>(on_true),-        static_cast<OnFalse&&>(on_false_));+        bool_, ASIO_MOVE_CAST(T)(on_true),+        ASIO_MOVE_CAST(OnFalse)(on_false_));   }    /// Set the false branch of the conditional.   template <typename T>   deferred_conditional<OnTrue, T> otherwise(T on_false,-      constraint_t<+      typename constraint<         is_deferred<T>::value-      >* = 0,-      constraint_t<+      >::type* = 0,+      typename constraint<         !is_same<-          conditional_t<true, OnTrue, T>,+          typename conditional<true, OnTrue, T>::type,           deferred_noop         >::value-      >* = 0,-      constraint_t<+      >::type* = 0,+      typename constraint<         is_same<-          conditional_t<true, OnFalse, T>,+          typename conditional<true, OnFalse, T>::type,           deferred_noop         >::value-      >* = 0) &&+      >::type* = 0) ASIO_RVALUE_REF_QUAL   {     return deferred_conditional<OnTrue, T>(-        bool_, static_cast<OnTrue&&>(on_true_),-        static_cast<T&&>(on_false));+        bool_, ASIO_MOVE_CAST(OnTrue)(on_true_),+        ASIO_MOVE_CAST(T)(on_false));   } };  #if !defined(GENERATING_DOCUMENTATION) template <typename OnTrue, typename OnFalse>-struct is_deferred<deferred_conditional<OnTrue, OnFalse>> : true_type+struct is_deferred<deferred_conditional<OnTrue, OnFalse> > : true_type { }; #endif // !defined(GENERATING_DOCUMENTATION)@@ -593,11 +663,8 @@  * The deferred_t class is used to indicate that an asynchronous operation  * should return a function object which is itself an initiation function. A  * deferred_t object may be passed as a completion token to an asynchronous- * operation, typically as the default completion token:- *- * @code auto my_deferred_op = my_socket.async_read_some(my_buffer); @endcode- *- * or by explicitly passing the special value @c asio::deferred:+ * operation, typically using the special value @c asio::deferred. For+ * example:  *  * @code auto my_deferred_op  *   = my_socket.async_read_some(my_buffer,@@ -610,7 +677,7 @@ { public:   /// Default constructor.-  constexpr deferred_t()+  ASIO_CONSTEXPR deferred_t()   {   } @@ -625,13 +692,13 @@     /// Construct the adapted executor from the inner executor type.     template <typename InnerExecutor1>     executor_with_default(const InnerExecutor1& ex,-        constraint_t<-          conditional_t<+        typename constraint<+          conditional<             !is_same<InnerExecutor1, executor_with_default>::value,             is_convertible<InnerExecutor1, InnerExecutor>,             false_type-          >::value-        > = 0) noexcept+          >::type::value+        >::type = 0) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -639,54 +706,59 @@    /// Type alias to adapt an I/O object to use @c deferred_t as its   /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)   template <typename T>   using as_default_on_t = typename T::template rebind_executor<-      executor_with_default<typename T::executor_type>>::other;+      executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)    /// Function helper to adapt an I/O object to use @c deferred_t as its   /// default completion token type.   template <typename T>-  static typename decay_t<T>::template rebind_executor<-      executor_with_default<typename decay_t<T>::executor_type>+  static typename decay<T>::type::template rebind_executor<+      executor_with_default<typename decay<T>::type::executor_type>     >::other-  as_default_on(T&& object)+  as_default_on(ASIO_MOVE_ARG(T) object)   {-    return typename decay_t<T>::template rebind_executor<-        executor_with_default<typename decay_t<T>::executor_type>-      >::other(static_cast<T&&>(object));+    return typename decay<T>::type::template rebind_executor<+        executor_with_default<typename decay<T>::type::executor_type>+      >::other(ASIO_MOVE_CAST(T)(object));   }    /// Creates a new deferred from a function.   template <typename Function>-  constraint_t<-    !is_deferred<decay_t<Function>>::value,-    deferred_function<decay_t<Function>>-  > operator()(Function&& function) const+  typename constraint<+    !is_deferred<typename decay<Function>::type>::value,+    deferred_function<typename decay<Function>::type>+  >::type operator()(ASIO_MOVE_ARG(Function) function) const   {-    return deferred_function<decay_t<Function>>(-        deferred_init_tag{}, static_cast<Function&&>(function));+    return deferred_function<typename decay<Function>::type>(+        deferred_init_tag{}, ASIO_MOVE_CAST(Function)(function));   }    /// Passes through anything that is already deferred.   template <typename T>-  constraint_t<-    is_deferred<decay_t<T>>::value,-    decay_t<T>-  > operator()(T&& t) const+  typename constraint<+    is_deferred<typename decay<T>::type>::value,+    typename decay<T>::type+  >::type operator()(ASIO_MOVE_ARG(T) t) const   {-    return static_cast<T&&>(t);+    return ASIO_MOVE_CAST(T)(t);   }    /// Returns a deferred operation that returns the provided values.   template <typename... Args>-  static constexpr deferred_values<decay_t<Args>...> values(Args&&... args)+  static ASIO_CONSTEXPR deferred_values<typename decay<Args>::type...>+  values(ASIO_MOVE_ARG(Args)... args)   {-    return deferred_values<decay_t<Args>...>(-        deferred_init_tag{}, static_cast<Args&&>(args)...);+    return deferred_values<typename decay<Args>::type...>(+        deferred_init_tag{}, ASIO_MOVE_CAST(Args)(args)...);   }    /// Creates a conditional object for branching deferred operations.-  static constexpr deferred_conditional<> when(bool b)+  static ASIO_CONSTEXPR deferred_conditional<> when(bool b)   {     return deferred_conditional<>(b);   }@@ -694,13 +766,15 @@  /// Pipe operator used to chain deferred operations. template <typename Head, typename Tail>-inline auto operator|(Head head, Tail&& tail)-  -> constraint_t<+inline auto operator|(Head head, ASIO_MOVE_ARG(Tail) tail)+  -> typename constraint<       is_deferred<Head>::value,-      decltype(static_cast<Head&&>(head)(static_cast<Tail&&>(tail)))-    >+      decltype(ASIO_MOVE_OR_LVALUE(Head)(head)(+            ASIO_MOVE_CAST(Tail)(tail)))+    >::type {-  return static_cast<Head&&>(head)(static_cast<Tail&&>(tail));+  return ASIO_MOVE_OR_LVALUE(Head)(head)(+      ASIO_MOVE_CAST(Tail)(tail)); }  /// A @ref completion_token object used to specify that an asynchronous@@ -708,12 +782,21 @@ /**  * See the documentation for asio::deferred_t for a usage example.  */-ASIO_INLINE_VARIABLE constexpr deferred_t deferred;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr deferred_t deferred;+#elif defined(ASIO_MSVC)+__declspec(selectany) deferred_t deferred;+#endif  } // namespace asio  #include "asio/detail/pop_options.hpp"  #include "asio/impl/deferred.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+       //     && defined(ASIO_HAS_DECLTYPE))+       //     && defined(ASIO_HAS_VARIADIC_TEMPLATES))+       //   || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_DEFERRED_HPP
link/modules/asio-standalone/asio/include/asio/detached.hpp view
@@ -2,7 +2,7 @@ // detached.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -38,8 +38,8 @@ class detached_t { public:-  /// Constructor.-  constexpr detached_t()+  /// Constructor. +  ASIO_CONSTEXPR detached_t()   {   } @@ -52,7 +52,7 @@     typedef detached_t default_completion_token_type;      /// Construct the adapted executor from the inner executor type.-    executor_with_default(const InnerExecutor& ex) noexcept+    executor_with_default(const InnerExecutor& ex) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -61,9 +61,9 @@     /// that to construct the adapted executor.     template <typename OtherExecutor>     executor_with_default(const OtherExecutor& ex,-        constraint_t<+        typename constraint<           is_convertible<OtherExecutor, InnerExecutor>::value-        > = 0) noexcept+        >::type = 0) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -71,21 +71,25 @@    /// Type alias to adapt an I/O object to use @c detached_t as its   /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)   template <typename T>   using as_default_on_t = typename T::template rebind_executor<-      executor_with_default<typename T::executor_type>>::other;+      executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)    /// Function helper to adapt an I/O object to use @c detached_t as its   /// default completion token type.   template <typename T>-  static typename decay_t<T>::template rebind_executor<-      executor_with_default<typename decay_t<T>::executor_type>+  static typename decay<T>::type::template rebind_executor<+      executor_with_default<typename decay<T>::type::executor_type>     >::other-  as_default_on(T&& object)+  as_default_on(ASIO_MOVE_ARG(T) object)   {-    return typename decay_t<T>::template rebind_executor<-        executor_with_default<typename decay_t<T>::executor_type>-      >::other(static_cast<T&&>(object));+    return typename decay<T>::type::template rebind_executor<+        executor_with_default<typename decay<T>::type::executor_type>+      >::other(ASIO_MOVE_CAST(T)(object));   } }; @@ -94,7 +98,11 @@ /**  * See the documentation for asio::detached_t for a usage example.  */-ASIO_INLINE_VARIABLE constexpr detached_t detached;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr detached_t detached;+#elif defined(ASIO_MSVC)+__declspec(selectany) detached_t detached;+#endif  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/detail/array.hpp view
@@ -2,7 +2,7 @@ // detail/array.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,12 +17,20 @@  #include "asio/detail/config.hpp" -#include <array>+#if defined(ASIO_HAS_STD_ARRAY)+# include <array>+#else // defined(ASIO_HAS_STD_ARRAY)+# include <boost/array.hpp>+#endif // defined(ASIO_HAS_STD_ARRAY)  namespace asio { namespace detail { +#if defined(ASIO_HAS_STD_ARRAY) using std::array;+#else // defined(ASIO_HAS_STD_ARRAY)+using boost::array;+#endif // defined(ASIO_HAS_STD_ARRAY)  } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/array_fwd.hpp view
@@ -2,7 +2,7 @@ // detail/array_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -27,6 +27,8 @@ // Standard library components can't be forward declared, so we'll have to // include the array header. Fortunately, it's fairly lightweight and doesn't // add significantly to the compile time.-#include <array>+#if defined(ASIO_HAS_STD_ARRAY)+# include <array>+#endif // defined(ASIO_HAS_STD_ARRAY)  #endif // ASIO_DETAIL_ARRAY_FWD_HPP
link/modules/asio-standalone/asio/include/asio/detail/assert.hpp view
@@ -2,7 +2,7 @@ // detail/assert.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/atomic_count.hpp view
@@ -2,7 +2,7 @@ // detail/atomic_count.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,9 +19,11 @@  #if !defined(ASIO_HAS_THREADS) // Nothing to include.-#else // !defined(ASIO_HAS_THREADS)+#elif defined(ASIO_HAS_STD_ATOMIC) # include <atomic>-#endif // !defined(ASIO_HAS_THREADS)+#else // defined(ASIO_HAS_STD_ATOMIC)+# include <boost/detail/atomic_count.hpp>+#endif // defined(ASIO_HAS_STD_ATOMIC)  namespace asio { namespace detail {@@ -32,7 +34,7 @@ inline void decrement(atomic_count& a, long b) { a -= b; } inline void ref_count_up(atomic_count& a) { ++a; } inline bool ref_count_down(atomic_count& a) { return --a == 0; }-#else // !defined(ASIO_HAS_THREADS)+#elif defined(ASIO_HAS_STD_ATOMIC) typedef std::atomic<long> atomic_count; inline void increment(atomic_count& a, long b) { a += b; } inline void decrement(atomic_count& a, long b) { a -= b; }@@ -51,7 +53,13 @@   }   return false; }-#endif // !defined(ASIO_HAS_THREADS)+#else // defined(ASIO_HAS_STD_ATOMIC)+typedef boost::detail::atomic_count atomic_count;+inline void increment(atomic_count& a, long b) { while (b > 0) ++a, --b; }+inline void decrement(atomic_count& a, long b) { while (b > 0) --a, --b; }+inline void ref_count_up(atomic_count& a) { ++a; }+inline bool ref_count_down(atomic_count& a) { return --a == 0; }+#endif // defined(ASIO_HAS_STD_ATOMIC)  } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/base_from_cancellation_state.hpp view
@@ -2,7 +2,7 @@ // detail/base_from_cancellation_state.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -31,12 +31,12 @@ public:   typedef cancellation_slot cancellation_slot_type; -  cancellation_slot_type get_cancellation_slot() const noexcept+  cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT   {     return cancellation_state_.slot();   } -  cancellation_state get_cancellation_state() const noexcept+  cancellation_state get_cancellation_state() const ASIO_NOEXCEPT   {     return cancellation_state_;   }@@ -57,12 +57,12 @@    template <typename InFilter, typename OutFilter>   base_from_cancellation_state(const Handler& handler,-      InFilter&& in_filter,-      OutFilter&& out_filter)+      ASIO_MOVE_ARG(InFilter) in_filter,+      ASIO_MOVE_ARG(OutFilter) out_filter)     : cancellation_state_(         asio::get_associated_cancellation_slot(handler),-        static_cast<InFilter&&>(in_filter),-        static_cast<OutFilter&&>(out_filter))+        ASIO_MOVE_CAST(InFilter)(in_filter),+        ASIO_MOVE_CAST(OutFilter)(out_filter))   {   } @@ -81,16 +81,16 @@    template <typename InFilter, typename OutFilter>   void reset_cancellation_state(const Handler& handler,-      InFilter&& in_filter,-      OutFilter&& out_filter)+      ASIO_MOVE_ARG(InFilter) in_filter,+      ASIO_MOVE_ARG(OutFilter) out_filter)   {     cancellation_state_ = cancellation_state(         asio::get_associated_cancellation_slot(handler),-        static_cast<InFilter&&>(in_filter),-        static_cast<OutFilter&&>(out_filter));+        ASIO_MOVE_CAST(InFilter)(in_filter),+        ASIO_MOVE_CAST(OutFilter)(out_filter));   } -  cancellation_type_t cancelled() const noexcept+  cancellation_type_t cancelled() const ASIO_NOEXCEPT   {     return cancellation_state_.cancelled();   }@@ -101,18 +101,17 @@  template <typename Handler> class base_from_cancellation_state<Handler,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_cancellation_slot<           Handler, cancellation_slot         >::asio_associated_cancellation_slot_is_unspecialised,         void       >::value-    >-  >+    >::type> { public:-  cancellation_state get_cancellation_state() const noexcept+  cancellation_state get_cancellation_state() const ASIO_NOEXCEPT   {     return cancellation_state();   }@@ -129,8 +128,8 @@    template <typename InFilter, typename OutFilter>   base_from_cancellation_state(const Handler&,-      InFilter&&,-      OutFilter&&)+      ASIO_MOVE_ARG(InFilter),+      ASIO_MOVE_ARG(OutFilter))   {   } @@ -145,12 +144,12 @@    template <typename InFilter, typename OutFilter>   void reset_cancellation_state(const Handler&,-      InFilter&&,-      OutFilter&&)+      ASIO_MOVE_ARG(InFilter),+      ASIO_MOVE_ARG(OutFilter))   {   } -  constexpr cancellation_type_t cancelled() const noexcept+  ASIO_CONSTEXPR cancellation_type_t cancelled() const ASIO_NOEXCEPT   {     return cancellation_type::none;   }
link/modules/asio-standalone/asio/include/asio/detail/base_from_completion_cond.hpp view
@@ -2,7 +2,7 @@ // detail/base_from_completion_cond.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -29,7 +29,7 @@ protected:   explicit base_from_completion_cond(CompletionCondition& completion_condition)     : completion_condition_(-        static_cast<CompletionCondition&&>(completion_condition))+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))   {   } 
link/modules/asio-standalone/asio/include/asio/detail/bind_handler.hpp view
@@ -2,7 +2,7 @@ // detail/bind_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,7 +17,9 @@  #include "asio/detail/config.hpp" #include "asio/associator.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp"  #include "asio/detail/push_options.hpp"@@ -30,29 +32,31 @@ { public:   template <typename T>-  binder0(int, T&& handler)-    : handler_(static_cast<T&&>(handler))+  binder0(int, ASIO_MOVE_ARG(T) handler)+    : handler_(ASIO_MOVE_CAST(T)(handler))   {   }    binder0(Handler& handler)-    : handler_(static_cast<Handler&&>(handler))+    : handler_(ASIO_MOVE_CAST(Handler)(handler))   {   } +#if defined(ASIO_HAS_MOVE)   binder0(const binder0& other)     : handler_(other.handler_)   {   }    binder0(binder0&& other)-    : handler_(static_cast<Handler&&>(other.handler_))+    : handler_(ASIO_MOVE_CAST(Handler)(other.handler_))   {   }+#endif // defined(ASIO_HAS_MOVE)    void operator()()   {-    static_cast<Handler&&>(handler_)();+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)();   }    void operator()() const@@ -65,6 +69,32 @@ };  template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    binder0<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    binder0<Handler>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation(     binder0<Handler>* this_handler) {@@ -72,12 +102,36 @@       this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    binder0<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    binder0<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler>-inline binder0<decay_t<Handler>> bind_handler(-    Handler&& handler)+inline binder0<typename decay<Handler>::type> bind_handler(+    ASIO_MOVE_ARG(Handler) handler) {-  return binder0<decay_t<Handler>>(-      0, static_cast<Handler&&>(handler));+  return binder0<typename decay<Handler>::type>(+      0, ASIO_MOVE_CAST(Handler)(handler)); }  template <typename Handler, typename Arg1>@@ -85,18 +139,19 @@ { public:   template <typename T>-  binder1(int, T&& handler, const Arg1& arg1)-    : handler_(static_cast<T&&>(handler)),+  binder1(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1)+    : handler_(ASIO_MOVE_CAST(T)(handler)),       arg1_(arg1)   {   }    binder1(Handler& handler, const Arg1& arg1)-    : handler_(static_cast<Handler&&>(handler)),+    : handler_(ASIO_MOVE_CAST(Handler)(handler)),       arg1_(arg1)   {   } +#if defined(ASIO_HAS_MOVE)   binder1(const binder1& other)     : handler_(other.handler_),       arg1_(other.arg1_)@@ -104,14 +159,15 @@   }    binder1(binder1&& other)-    : handler_(static_cast<Handler&&>(other.handler_)),-      arg1_(static_cast<Arg1&&>(other.arg1_))+    : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+      arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_))   {   }+#endif // defined(ASIO_HAS_MOVE)    void operator()()   {-    static_cast<Handler&&>(handler_)(+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(         static_cast<const Arg1&>(arg1_));   } @@ -126,6 +182,32 @@ };  template <typename Handler, typename Arg1>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    binder1<Handler, Arg1>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    binder1<Handler, Arg1>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1> inline bool asio_handler_is_continuation(     binder1<Handler, Arg1>* this_handler) {@@ -133,12 +215,36 @@       this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    binder1<Handler, Arg1>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Arg1>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    binder1<Handler, Arg1>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1>-inline binder1<decay_t<Handler>, Arg1> bind_handler(-    Handler&& handler, const Arg1& arg1)+inline binder1<typename decay<Handler>::type, Arg1> bind_handler(+    ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1) {-  return binder1<decay_t<Handler>, Arg1>(0,-      static_cast<Handler&&>(handler), arg1);+  return binder1<typename decay<Handler>::type, Arg1>(0,+      ASIO_MOVE_CAST(Handler)(handler), arg1); }  template <typename Handler, typename Arg1, typename Arg2>@@ -146,21 +252,22 @@ { public:   template <typename T>-  binder2(int, T&& handler,+  binder2(int, ASIO_MOVE_ARG(T) handler,       const Arg1& arg1, const Arg2& arg2)-    : handler_(static_cast<T&&>(handler)),+    : handler_(ASIO_MOVE_CAST(T)(handler)),       arg1_(arg1),       arg2_(arg2)   {   }    binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2)-    : handler_(static_cast<Handler&&>(handler)),+    : handler_(ASIO_MOVE_CAST(Handler)(handler)),       arg1_(arg1),       arg2_(arg2)   {   } +#if defined(ASIO_HAS_MOVE)   binder2(const binder2& other)     : handler_(other.handler_),       arg1_(other.arg1_),@@ -169,15 +276,16 @@   }    binder2(binder2&& other)-    : handler_(static_cast<Handler&&>(other.handler_)),-      arg1_(static_cast<Arg1&&>(other.arg1_)),-      arg2_(static_cast<Arg2&&>(other.arg2_))+    : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+      arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+      arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_))   {   }+#endif // defined(ASIO_HAS_MOVE)    void operator()()   {-    static_cast<Handler&&>(handler_)(+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(         static_cast<const Arg1&>(arg1_),         static_cast<const Arg2&>(arg2_));   }@@ -194,6 +302,32 @@ };  template <typename Handler, typename Arg1, typename Arg2>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    binder2<Handler, Arg1, Arg2>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    binder2<Handler, Arg1, Arg2>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2> inline bool asio_handler_is_continuation(     binder2<Handler, Arg1, Arg2>* this_handler) {@@ -201,12 +335,36 @@       this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1, typename Arg2>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    binder2<Handler, Arg1, Arg2>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Arg1, typename Arg2>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    binder2<Handler, Arg1, Arg2>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1, typename Arg2>-inline binder2<decay_t<Handler>, Arg1, Arg2> bind_handler(-    Handler&& handler, const Arg1& arg1, const Arg2& arg2)+inline binder2<typename decay<Handler>::type, Arg1, Arg2> bind_handler(+    ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2) {-  return binder2<decay_t<Handler>, Arg1, Arg2>(0,-      static_cast<Handler&&>(handler), arg1, arg2);+  return binder2<typename decay<Handler>::type, Arg1, Arg2>(0,+      ASIO_MOVE_CAST(Handler)(handler), arg1, arg2); }  template <typename Handler, typename Arg1, typename Arg2, typename Arg3>@@ -214,9 +372,9 @@ { public:   template <typename T>-  binder3(int, T&& handler, const Arg1& arg1,+  binder3(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1,       const Arg2& arg2, const Arg3& arg3)-    : handler_(static_cast<T&&>(handler)),+    : handler_(ASIO_MOVE_CAST(T)(handler)),       arg1_(arg1),       arg2_(arg2),       arg3_(arg3)@@ -225,13 +383,14 @@    binder3(Handler& handler, const Arg1& arg1,       const Arg2& arg2, const Arg3& arg3)-    : handler_(static_cast<Handler&&>(handler)),+    : handler_(ASIO_MOVE_CAST(Handler)(handler)),       arg1_(arg1),       arg2_(arg2),       arg3_(arg3)   {   } +#if defined(ASIO_HAS_MOVE)   binder3(const binder3& other)     : handler_(other.handler_),       arg1_(other.arg1_),@@ -241,16 +400,17 @@   }    binder3(binder3&& other)-    : handler_(static_cast<Handler&&>(other.handler_)),-      arg1_(static_cast<Arg1&&>(other.arg1_)),-      arg2_(static_cast<Arg2&&>(other.arg2_)),-      arg3_(static_cast<Arg3&&>(other.arg3_))+    : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+      arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+      arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)),+      arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_))   {   }+#endif // defined(ASIO_HAS_MOVE)    void operator()()   {-    static_cast<Handler&&>(handler_)(+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(         static_cast<const Arg1&>(arg1_),         static_cast<const Arg2&>(arg2_),         static_cast<const Arg3&>(arg3_));@@ -269,6 +429,32 @@ };  template <typename Handler, typename Arg1, typename Arg2, typename Arg3>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2, typename Arg3>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2, typename Arg3> inline bool asio_handler_is_continuation(     binder3<Handler, Arg1, Arg2, Arg3>* this_handler) {@@ -276,13 +462,39 @@       this_handler->handler_); } +template <typename Function, typename Handler,+    typename Arg1, typename Arg2, typename Arg3>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler,+    typename Arg1, typename Arg2, typename Arg3>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1, typename Arg2, typename Arg3>-inline binder3<decay_t<Handler>, Arg1, Arg2, Arg3> bind_handler(-    Handler&& handler, const Arg1& arg1, const Arg2& arg2,+inline binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3> bind_handler(+    ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2,     const Arg3& arg3) {-  return binder3<decay_t<Handler>, Arg1, Arg2, Arg3>(0,-      static_cast<Handler&&>(handler), arg1, arg2, arg3);+  return binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3>(0,+      ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3); }  template <typename Handler, typename Arg1,@@ -291,9 +503,9 @@ { public:   template <typename T>-  binder4(int, T&& handler, const Arg1& arg1,+  binder4(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1,       const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)-    : handler_(static_cast<T&&>(handler)),+    : handler_(ASIO_MOVE_CAST(T)(handler)),       arg1_(arg1),       arg2_(arg2),       arg3_(arg3),@@ -303,7 +515,7 @@    binder4(Handler& handler, const Arg1& arg1,       const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)-    : handler_(static_cast<Handler&&>(handler)),+    : handler_(ASIO_MOVE_CAST(Handler)(handler)),       arg1_(arg1),       arg2_(arg2),       arg3_(arg3),@@ -311,6 +523,7 @@   {   } +#if defined(ASIO_HAS_MOVE)   binder4(const binder4& other)     : handler_(other.handler_),       arg1_(other.arg1_),@@ -321,17 +534,18 @@   }    binder4(binder4&& other)-    : handler_(static_cast<Handler&&>(other.handler_)),-      arg1_(static_cast<Arg1&&>(other.arg1_)),-      arg2_(static_cast<Arg2&&>(other.arg2_)),-      arg3_(static_cast<Arg3&&>(other.arg3_)),-      arg4_(static_cast<Arg4&&>(other.arg4_))+    : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+      arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+      arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)),+      arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)),+      arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_))   {   }+#endif // defined(ASIO_HAS_MOVE)    void operator()()   {-    static_cast<Handler&&>(handler_)(+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(         static_cast<const Arg1&>(arg1_),         static_cast<const Arg2&>(arg2_),         static_cast<const Arg3&>(arg3_),@@ -353,6 +567,34 @@  template <typename Handler, typename Arg1,     typename Arg2, typename Arg3, typename Arg4>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1,+    typename Arg2, typename Arg3, typename Arg4>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1,+    typename Arg2, typename Arg3, typename Arg4> inline bool asio_handler_is_continuation(     binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler) {@@ -360,14 +602,40 @@       this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1,+    typename Arg2, typename Arg3, typename Arg4>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Arg1,+    typename Arg2, typename Arg3, typename Arg4>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1,     typename Arg2, typename Arg3, typename Arg4>-inline binder4<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4>-bind_handler(Handler&& handler, const Arg1& arg1,+inline binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>+bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,     const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) {-  return binder4<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4>(0,-      static_cast<Handler&&>(handler), arg1, arg2, arg3, arg4);+  return binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>(0,+      ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4); }  template <typename Handler, typename Arg1, typename Arg2,@@ -376,9 +644,9 @@ { public:   template <typename T>-  binder5(int, T&& handler, const Arg1& arg1,+  binder5(int, ASIO_MOVE_ARG(T) handler, const Arg1& arg1,       const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)-    : handler_(static_cast<T&&>(handler)),+    : handler_(ASIO_MOVE_CAST(T)(handler)),       arg1_(arg1),       arg2_(arg2),       arg3_(arg3),@@ -389,7 +657,7 @@    binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2,       const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)-    : handler_(static_cast<Handler&&>(handler)),+    : handler_(ASIO_MOVE_CAST(Handler)(handler)),       arg1_(arg1),       arg2_(arg2),       arg3_(arg3),@@ -398,6 +666,7 @@   {   } +#if defined(ASIO_HAS_MOVE)   binder5(const binder5& other)     : handler_(other.handler_),       arg1_(other.arg1_),@@ -409,18 +678,19 @@   }    binder5(binder5&& other)-    : handler_(static_cast<Handler&&>(other.handler_)),-      arg1_(static_cast<Arg1&&>(other.arg1_)),-      arg2_(static_cast<Arg2&&>(other.arg2_)),-      arg3_(static_cast<Arg3&&>(other.arg3_)),-      arg4_(static_cast<Arg4&&>(other.arg4_)),-      arg5_(static_cast<Arg5&&>(other.arg5_))+    : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+      arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+      arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_)),+      arg3_(ASIO_MOVE_CAST(Arg3)(other.arg3_)),+      arg4_(ASIO_MOVE_CAST(Arg4)(other.arg4_)),+      arg5_(ASIO_MOVE_CAST(Arg5)(other.arg5_))   {   }+#endif // defined(ASIO_HAS_MOVE)    void operator()()   {-    static_cast<Handler&&>(handler_)(+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(         static_cast<const Arg1&>(arg1_),         static_cast<const Arg2&>(arg2_),         static_cast<const Arg3&>(arg3_),@@ -444,6 +714,34 @@  template <typename Handler, typename Arg1, typename Arg2,     typename Arg3, typename Arg4, typename Arg5>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2,+    typename Arg3, typename Arg4, typename Arg5>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2,+    typename Arg3, typename Arg4, typename Arg5> inline bool asio_handler_is_continuation(     binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler) {@@ -451,37 +749,65 @@       this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1,+    typename Arg2, typename Arg3, typename Arg4, typename Arg5>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Arg1,+    typename Arg2, typename Arg3, typename Arg4, typename Arg5>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1, typename Arg2,     typename Arg3, typename Arg4, typename Arg5>-inline binder5<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4, Arg5>-bind_handler(Handler&& handler, const Arg1& arg1,+inline binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>+bind_handler(ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,     const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5) {-  return binder5<decay_t<Handler>, Arg1, Arg2, Arg3, Arg4, Arg5>(0,-      static_cast<Handler&&>(handler), arg1, arg2, arg3, arg4, arg5);+  return binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0,+      ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5); } +#if defined(ASIO_HAS_MOVE)+ template <typename Handler, typename Arg1> class move_binder1 { public:-  move_binder1(int, Handler&& handler,-      Arg1&& arg1)-    : handler_(static_cast<Handler&&>(handler)),-      arg1_(static_cast<Arg1&&>(arg1))+  move_binder1(int, ASIO_MOVE_ARG(Handler) handler,+      ASIO_MOVE_ARG(Arg1) arg1)+    : handler_(ASIO_MOVE_CAST(Handler)(handler)),+      arg1_(ASIO_MOVE_CAST(Arg1)(arg1))   {   }    move_binder1(move_binder1&& other)-    : handler_(static_cast<Handler&&>(other.handler_)),-      arg1_(static_cast<Arg1&&>(other.arg1_))+    : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+      arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_))   {   }    void operator()()   {-    static_cast<Handler&&>(handler_)(-        static_cast<Arg1&&>(arg1_));+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        ASIO_MOVE_CAST(Arg1)(arg1_));   }  //private:@@ -490,6 +816,32 @@ };  template <typename Handler, typename Arg1>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    move_binder1<Handler, Arg1>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    move_binder1<Handler, Arg1>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1> inline bool asio_handler_is_continuation(     move_binder1<Handler, Arg1>* this_handler) {@@ -497,30 +849,42 @@       this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(ASIO_MOVE_ARG(Function) function,+    move_binder1<Handler, Arg1>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      ASIO_MOVE_CAST(Function)(function), this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Handler, typename Arg1, typename Arg2> class move_binder2 { public:-  move_binder2(int, Handler&& handler,-      const Arg1& arg1, Arg2&& arg2)-    : handler_(static_cast<Handler&&>(handler)),+  move_binder2(int, ASIO_MOVE_ARG(Handler) handler,+      const Arg1& arg1, ASIO_MOVE_ARG(Arg2) arg2)+    : handler_(ASIO_MOVE_CAST(Handler)(handler)),       arg1_(arg1),-      arg2_(static_cast<Arg2&&>(arg2))+      arg2_(ASIO_MOVE_CAST(Arg2)(arg2))   {   }    move_binder2(move_binder2&& other)-    : handler_(static_cast<Handler&&>(other.handler_)),-      arg1_(static_cast<Arg1&&>(other.arg1_)),-      arg2_(static_cast<Arg2&&>(other.arg2_))+    : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+      arg1_(ASIO_MOVE_CAST(Arg1)(other.arg1_)),+      arg2_(ASIO_MOVE_CAST(Arg2)(other.arg2_))   {   }    void operator()()   {-    static_cast<Handler&&>(handler_)(+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(         static_cast<const Arg1&>(arg1_),-        static_cast<Arg2&&>(arg2_));+        ASIO_MOVE_CAST(Arg2)(arg2_));   }  //private:@@ -530,6 +894,32 @@ };  template <typename Handler, typename Arg1, typename Arg2>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    move_binder2<Handler, Arg1, Arg2>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    move_binder2<Handler, Arg1, Arg2>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Arg1, typename Arg2> inline bool asio_handler_is_continuation(     move_binder2<Handler, Arg1, Arg2>* this_handler) {@@ -537,6 +927,20 @@       this_handler->handler_); } +template <typename Function, typename Handler, typename Arg1, typename Arg2>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(ASIO_MOVE_ARG(Function) function,+    move_binder2<Handler, Arg1, Arg2>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      ASIO_MOVE_CAST(Function)(function), this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++#endif // defined(ASIO_HAS_MOVE)+ } // namespace detail  template <template <typename, typename> class Associator,@@ -545,15 +949,18 @@     detail::binder0<Handler>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::binder0<Handler>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::binder0<Handler>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::binder0<Handler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::binder0<Handler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }@@ -565,15 +972,18 @@     detail::binder1<Handler, Arg1>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::binder1<Handler, Arg1>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::binder1<Handler, Arg1>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::binder1<Handler, Arg1>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::binder1<Handler, Arg1>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }@@ -586,15 +996,18 @@     detail::binder2<Handler, Arg1, Arg2>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::binder2<Handler, Arg1, Arg2>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::binder2<Handler, Arg1, Arg2>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::binder2<Handler, Arg1, Arg2>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::binder2<Handler, Arg1, Arg2>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }@@ -607,15 +1020,18 @@     detail::binder3<Handler, Arg1, Arg2, Arg3>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::binder3<Handler, Arg1, Arg2, Arg3>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::binder3<Handler, Arg1, Arg2, Arg3>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }@@ -628,15 +1044,19 @@     detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h)+    ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::binder4<Handler, Arg1, Arg2, Arg3, Arg4>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }@@ -649,60 +1069,74 @@     detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h)+    ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   } }; +#if defined(ASIO_HAS_MOVE)+ template <template <typename, typename> class Associator,     typename Handler, typename Arg1, typename DefaultCandidate> struct associator<Associator,     detail::move_binder1<Handler, Arg1>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::move_binder1<Handler, Arg1>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::move_binder1<Handler, Arg1>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::move_binder1<Handler, Arg1>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::move_binder1<Handler, Arg1>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   } };  template <template <typename, typename> class Associator,-    typename Handler, typename Arg1, typename Arg2, typename DefaultCandidate>+    typename Handler, typename Arg1, typename Arg2,+    typename DefaultCandidate> struct associator<Associator,     detail::move_binder2<Handler, Arg1, Arg2>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::move_binder2<Handler, Arg1, Arg2>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::move_binder2<Handler, Arg1, Arg2>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::move_binder2<Handler, Arg1, Arg2>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::move_binder2<Handler, Arg1, Arg2>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   } };++#endif // defined(ASIO_HAS_MOVE)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/detail/blocking_executor_op.hpp view
@@ -2,7 +2,7 @@ // detail/blocking_executor_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,7 @@ #include "asio/detail/config.hpp" #include "asio/detail/event.hpp" #include "asio/detail/fenced_block.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/scheduler_operation.hpp" @@ -90,7 +91,7 @@     {       fenced_block b(fenced_block::half);       ASIO_HANDLER_INVOCATION_BEGIN(());-      static_cast<Handler&&>(o->handler_)();+      asio_handler_invoke_helpers::invoke(o->handler_, o->handler_);       ASIO_HANDLER_INVOCATION_END;     }   }
link/modules/asio-standalone/asio/include/asio/detail/buffer_resize_guard.hpp view
@@ -2,7 +2,7 @@ // detail/buffer_resize_guard.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/buffer_sequence_adapter.hpp view
@@ -2,7 +2,7 @@ // detail/buffer_sequence_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -385,7 +385,147 @@   std::size_t total_buffer_size_; }; +#if !defined(ASIO_NO_DEPRECATED)+ template <typename Buffer>+class buffer_sequence_adapter<Buffer, asio::mutable_buffers_1>+  : buffer_sequence_adapter_base+{+public:+  enum { is_single_buffer = true };+  enum { is_registered_buffer = false };++  explicit buffer_sequence_adapter(+      const asio::mutable_buffers_1& buffer_sequence)+  {+    init_native_buffer(buffer_, Buffer(buffer_sequence));+    total_buffer_size_ = buffer_sequence.size();+  }++  native_buffer_type* buffers()+  {+    return &buffer_;+  }++  std::size_t count() const+  {+    return 1;+  }++  std::size_t total_size() const+  {+    return total_buffer_size_;+  }++  registered_buffer_id registered_id() const+  {+    return registered_buffer_id();+  }++  bool all_empty() const+  {+    return total_buffer_size_ == 0;+  }++  static bool all_empty(const asio::mutable_buffers_1& buffer_sequence)+  {+    return buffer_sequence.size() == 0;+  }++  static void validate(const asio::mutable_buffers_1& buffer_sequence)+  {+    buffer_sequence.data();+  }++  static Buffer first(const asio::mutable_buffers_1& buffer_sequence)+  {+    return Buffer(buffer_sequence);+  }++  enum { linearisation_storage_size = 1 };++  static Buffer linearise(const asio::mutable_buffers_1& buffer_sequence,+      const Buffer&)+  {+    return Buffer(buffer_sequence);+  }++private:+  native_buffer_type buffer_;+  std::size_t total_buffer_size_;+};++template <typename Buffer>+class buffer_sequence_adapter<Buffer, asio::const_buffers_1>+  : buffer_sequence_adapter_base+{+public:+  enum { is_single_buffer = true };+  enum { is_registered_buffer = false };++  explicit buffer_sequence_adapter(+      const asio::const_buffers_1& buffer_sequence)+  {+    init_native_buffer(buffer_, Buffer(buffer_sequence));+    total_buffer_size_ = buffer_sequence.size();+  }++  native_buffer_type* buffers()+  {+    return &buffer_;+  }++  std::size_t count() const+  {+    return 1;+  }++  std::size_t total_size() const+  {+    return total_buffer_size_;+  }++  registered_buffer_id registered_id() const+  {+    return registered_buffer_id();+  }++  bool all_empty() const+  {+    return total_buffer_size_ == 0;+  }++  static bool all_empty(const asio::const_buffers_1& buffer_sequence)+  {+    return buffer_sequence.size() == 0;+  }++  static void validate(const asio::const_buffers_1& buffer_sequence)+  {+    buffer_sequence.data();+  }++  static Buffer first(const asio::const_buffers_1& buffer_sequence)+  {+    return Buffer(buffer_sequence);+  }++  enum { linearisation_storage_size = 1 };++  static Buffer linearise(const asio::const_buffers_1& buffer_sequence,+      const Buffer&)+  {+    return Buffer(buffer_sequence);+  }++private:+  native_buffer_type buffer_;+  std::size_t total_buffer_size_;+};++#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Buffer> class buffer_sequence_adapter<Buffer, asio::mutable_registered_buffer>   : buffer_sequence_adapter_base {@@ -534,7 +674,7 @@ };  template <typename Buffer, typename Elem>-class buffer_sequence_adapter<Buffer, boost::array<Elem, 2>>+class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >   : buffer_sequence_adapter_base { public:@@ -609,8 +749,10 @@   std::size_t total_buffer_size_; }; +#if defined(ASIO_HAS_STD_ARRAY)+ template <typename Buffer, typename Elem>-class buffer_sequence_adapter<Buffer, std::array<Elem, 2>>+class buffer_sequence_adapter<Buffer, std::array<Elem, 2> >   : buffer_sequence_adapter_base { public:@@ -684,6 +826,8 @@   native_buffer_type buffers_[2];   std::size_t total_buffer_size_; };++#endif // defined(ASIO_HAS_STD_ARRAY)  } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/buffered_stream_storage.hpp view
@@ -2,7 +2,7 @@ // detail/buffered_stream_storage.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -113,7 +113,7 @@    // The offset to the end of the unread data.   size_type end_offset_;-+     // The data in the buffer.   std::vector<byte_type> buffer_; };
+ link/modules/asio-standalone/asio/include/asio/detail/bulk_executor_op.hpp view
@@ -0,0 +1,89 @@+//+// detail/bulk_executor_op.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_BULK_EXECUTOR_OP_HPP+#define ASIO_DETAIL_BULK_EXECUTOR_OP_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/bind_handler.hpp"+#include "asio/detail/fenced_block.hpp"+#include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp"+#include "asio/detail/scheduler_operation.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++template <typename Handler, typename Alloc,+    typename Operation = scheduler_operation>+class bulk_executor_op : public Operation+{+public:+  ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(bulk_executor_op);++  template <typename H>+  bulk_executor_op(ASIO_MOVE_ARG(H) h,+      const Alloc& allocator, std::size_t i)+    : Operation(&bulk_executor_op::do_complete),+      handler_(ASIO_MOVE_CAST(H)(h)),+      allocator_(allocator),+      index_(i)+  {+  }++  static void do_complete(void* owner, Operation* base,+      const asio::error_code& /*ec*/,+      std::size_t /*bytes_transferred*/)+  {+    // Take ownership of the handler object.+    ASIO_ASSUME(base != 0);+    bulk_executor_op* o(static_cast<bulk_executor_op*>(base));+    Alloc allocator(o->allocator_);+    ptr p = { detail::addressof(allocator), o, o };++    ASIO_HANDLER_COMPLETION((*o));++    // Make a copy of the handler so that the memory can be deallocated before+    // the upcall is made. Even if we're not about to make an upcall, a+    // sub-object of the handler may be the true owner of the memory associated+    // with the handler. Consequently, a local copy of the handler is required+    // to ensure that any owning sub-object remains valid until after we have+    // deallocated the memory here.+    detail::binder1<Handler, std::size_t> handler(o->handler_, o->index_);+    p.reset();++    // Make the upcall if required.+    if (owner)+    {+      fenced_block b(fenced_block::half);+      ASIO_HANDLER_INVOCATION_BEGIN(());+      asio_handler_invoke_helpers::invoke(handler, handler.handler_);+      ASIO_HANDLER_INVOCATION_END;+    }+  }++private:+  Handler handler_;+  Alloc allocator_;+  std::size_t index_;+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_DETAIL_BULK_EXECUTOR_OP_HPP
link/modules/asio-standalone/asio/include/asio/detail/call_stack.hpp view
@@ -2,7 +2,7 @@ // detail/call_stack.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/chrono.hpp view
@@ -2,7 +2,7 @@ // detail/chrono.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,11 +16,17 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <chrono> +#if defined(ASIO_HAS_STD_CHRONO)+# include <chrono>+#elif defined(ASIO_HAS_BOOST_CHRONO)+# include <boost/chrono/system_clocks.hpp>+#endif // defined(ASIO_HAS_BOOST_CHRONO)+ namespace asio { namespace chrono { +#if defined(ASIO_HAS_STD_CHRONO) using std::chrono::duration; using std::chrono::time_point; using std::chrono::duration_cast;@@ -38,6 +44,21 @@ #endif // defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK) using std::chrono::system_clock; using std::chrono::high_resolution_clock;+#elif defined(ASIO_HAS_BOOST_CHRONO)+using boost::chrono::duration;+using boost::chrono::time_point;+using boost::chrono::duration_cast;+using boost::chrono::nanoseconds;+using boost::chrono::microseconds;+using boost::chrono::milliseconds;+using boost::chrono::seconds;+using boost::chrono::minutes;+using boost::chrono::hours;+using boost::chrono::time_point_cast;+using boost::chrono::system_clock;+using boost::chrono::steady_clock;+using boost::chrono::high_resolution_clock;+#endif // defined(ASIO_HAS_BOOST_CHRONO)  } // namespace chrono } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/chrono_time_traits.hpp view
@@ -2,7 +2,7 @@ // detail/chrono_time_traits.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/completion_handler.hpp view
@@ -2,7 +2,7 @@ // detail/completion_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -35,7 +35,7 @@    completion_handler(Handler& h, const IoExecutor& io_ex)     : operation(&completion_handler::do_complete),-      handler_(static_cast<Handler&&>(h)),+      handler_(ASIO_MOVE_CAST(Handler)(h)),       work_(handler_, io_ex)   {   }@@ -52,7 +52,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           h->work_));      // Make a copy of the handler so that the memory can be deallocated before@@ -61,7 +61,7 @@     // with the handler. Consequently, a local copy of the handler is required     // to ensure that any owning sub-object remains valid until after we have     // deallocated the memory here.-    Handler handler(static_cast<Handler&&>(h->handler_));+    Handler handler(ASIO_MOVE_CAST(Handler)(h->handler_));     p.h = asio::detail::addressof(handler);     p.reset(); 
− link/modules/asio-standalone/asio/include/asio/detail/completion_message.hpp
@@ -1,127 +0,0 @@-//-// detail/completion_message.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DETAIL_COMPLETION_MESSAGE_HPP-#define ASIO_DETAIL_COMPLETION_MESSAGE_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include <tuple>-#include "asio/detail/type_traits.hpp"-#include "asio/detail/utility.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Signature>-class completion_message;--template <typename R>-class completion_message<R()>-{-public:-  completion_message(int)-  {-  }--  template <typename Handler>-  void receive(Handler& handler)-  {-    static_cast<Handler&&>(handler)();-  }-};--template <typename R, typename Arg0>-class completion_message<R(Arg0)>-{-public:-  template <typename T0>-  completion_message(int, T0&& t0)-    : arg0_(static_cast<T0&&>(t0))-  {-  }--  template <typename Handler>-  void receive(Handler& handler)-  {-    static_cast<Handler&&>(handler)(-        static_cast<arg0_type&&>(arg0_));-  }--private:-  typedef decay_t<Arg0> arg0_type;-  arg0_type arg0_;-};--template <typename R, typename Arg0, typename Arg1>-class completion_message<R(Arg0, Arg1)>-{-public:-  template <typename T0, typename T1>-  completion_message(int, T0&& t0, T1&& t1)-    : arg0_(static_cast<T0&&>(t0)),-      arg1_(static_cast<T1&&>(t1))-  {-  }--  template <typename Handler>-  void receive(Handler& handler)-  {-    static_cast<Handler&&>(handler)(-        static_cast<arg0_type&&>(arg0_),-        static_cast<arg1_type&&>(arg1_));-  }--private:-  typedef decay_t<Arg0> arg0_type;-  arg0_type arg0_;-  typedef decay_t<Arg1> arg1_type;-  arg1_type arg1_;-};--template <typename R, typename... Args>-class completion_message<R(Args...)>-{-public:-  template <typename... T>-  completion_message(int, T&&... t)-    : args_(static_cast<T&&>(t)...)-  {-  }--  template <typename Handler>-  void receive(Handler& h)-  {-    this->do_receive(h, asio::detail::index_sequence_for<Args...>());-  }--private:-  template <typename Handler, std::size_t... I>-  void do_receive(Handler& h, asio::detail::index_sequence<I...>)-  {-    static_cast<Handler&&>(h)(-        std::get<I>(static_cast<args_type&&>(args_))...);-  }--  typedef std::tuple<decay_t<Args>...> args_type;-  args_type args_;-};--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_COMPLETION_MESSAGE_HPP
− link/modules/asio-standalone/asio/include/asio/detail/completion_payload.hpp
@@ -1,220 +0,0 @@-//-// detail/completion_payload.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DETAIL_COMPLETION_PAYLOAD_HPP-#define ASIO_DETAIL_COMPLETION_PAYLOAD_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/error_code.hpp"-#include "asio/detail/completion_message.hpp"--#if defined(ASIO_HAS_STD_VARIANT)-# include <variant>-#else // defined(ASIO_HAS_STD_VARIANT)-# include <new>-#endif // defined(ASIO_HAS_STD_VARIANT)--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename... Signatures>-class completion_payload;--template <typename R>-class completion_payload<R()>-{-public:-  explicit completion_payload(completion_message<R()>)-  {-  }--  template <typename Handler>-  void receive(Handler& handler)-  {-    static_cast<Handler&&>(handler)();-  }-};--template <typename Signature>-class completion_payload<Signature>-{-public:-  completion_payload(completion_message<Signature>&& m)-    : message_(static_cast<completion_message<Signature>&&>(m))-  {-  }--  template <typename Handler>-  void receive(Handler& handler)-  {-    message_.receive(handler);-  }--private:-  completion_message<Signature> message_;-};--#if defined(ASIO_HAS_STD_VARIANT)--template <typename... Signatures>-class completion_payload-{-public:-  template <typename Signature>-  completion_payload(completion_message<Signature>&& m)-    : message_(static_cast<completion_message<Signature>&&>(m))-  {-  }--  template <typename Handler>-  void receive(Handler& handler)-  {-    std::visit(-        [&](auto& message)-        {-          message.receive(handler);-        }, message_);-  }--private:-  std::variant<completion_message<Signatures>...> message_;-};--#else // defined(ASIO_HAS_STD_VARIANT)--template <typename R1, typename R2>-class completion_payload<R1(), R2(asio::error_code)>-{-public:-  typedef completion_message<R1()> void_message_type;-  typedef completion_message<R2(asio::error_code)> error_message_type;--  completion_payload(void_message_type&&)-    : message_(0, asio::error_code()),-      empty_(true)-  {-  }--  completion_payload(error_message_type&& m)-    : message_(static_cast<error_message_type&&>(m)),-      empty_(false)-  {-  }--  template <typename Handler>-  void receive(Handler& handler)-  {-    if (empty_)-      completion_message<R1()>(0).receive(handler);-    else-      message_.receive(handler);-  }--private:-  error_message_type message_;-  bool empty_;-};--template <typename Sig1, typename Sig2>-class completion_payload<Sig1, Sig2>-{-public:-  typedef completion_message<Sig1> message_1_type;-  typedef completion_message<Sig2> message_2_type;--  completion_payload(message_1_type&& m)-    : index_(1)-  {-    new (&storage_.message_1_) message_1_type(static_cast<message_1_type&&>(m));-  }--  completion_payload(message_2_type&& m)-    : index_(2)-  {-    new (&storage_.message_2_) message_2_type(static_cast<message_2_type&&>(m));-  }--  completion_payload(completion_payload&& other)-    : index_(other.index_)-  {-    switch (index_)-    {-    case 1:-      new (&storage_.message_1_) message_1_type(-          static_cast<message_1_type&&>(other.storage_.message_1_));-      break;-    case 2:-      new (&storage_.message_2_) message_2_type(-          static_cast<message_2_type&&>(other.storage_.message_2_));-      break;-    default:-      break;-    }-  }--  ~completion_payload()-  {-    switch (index_)-    {-    case 1:-      storage_.message_1_.~message_1_type();-      break;-    case 2:-      storage_.message_2_.~message_2_type();-      break;-    default:-      break;-    }-  }--  template <typename Handler>-  void receive(Handler& handler)-  {-    switch (index_)-    {-    case 1:-      storage_.message_1_.receive(handler);-      break;-    case 2:-      storage_.message_2_.receive(handler);-      break;-    default:-      break;-    }-  }--private:-  union storage-  {-    storage() {}-    ~storage() {}--    char dummy_;-    message_1_type message_1_;-    message_2_type message_2_;-  } storage_;-  unsigned char index_;-};--#endif // defined(ASIO_HAS_STD_VARIANT)--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_COMPLETION_PAYLOAD_HPP
− link/modules/asio-standalone/asio/include/asio/detail/completion_payload_handler.hpp
@@ -1,79 +0,0 @@-//-// detail/completion_payload_handler.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DETAIL_COMPLETION_PAYLOAD_HANDLER_HPP-#define ASIO_DETAIL_COMPLETION_PAYLOAD_HANDLER_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associator.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Payload, typename Handler>-class completion_payload_handler-{-public:-  completion_payload_handler(Payload&& p, Handler& h)-    : payload_(static_cast<Payload&&>(p)),-      handler_(static_cast<Handler&&>(h))-  {-  }--  void operator()()-  {-    payload_.receive(handler_);-  }--  Handler& handler()-  {-    return handler_;-  }--//private:-  Payload payload_;-  Handler handler_;-};--} // namespace detail--template <template <typename, typename> class Associator,-    typename Payload, typename Handler, typename DefaultCandidate>-struct associator<Associator,-    detail::completion_payload_handler<Payload, Handler>,-    DefaultCandidate>-  : Associator<Handler, DefaultCandidate>-{-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::completion_payload_handler<Payload, Handler>& h) noexcept-  {-    return Associator<Handler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(-      const detail::completion_payload_handler<Payload, Handler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<Handler, DefaultCandidate>::get(h.handler_, c);-  }-};--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_COMPLETION_PAYLOAD_HANDLER_HPP
link/modules/asio-standalone/asio/include/asio/detail/composed_work.hpp view
@@ -2,7 +2,7 @@ // detail/composed_work.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,6 +17,7 @@  #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/executor_work_guard.hpp"@@ -32,9 +33,11 @@ class composed_work_guard { public:-  typedef decay_t<-      prefer_result_t<Executor, execution::outstanding_work_t::tracked_t>-    > executor_type;+  typedef typename decay<+      typename prefer_result<Executor,+        execution::outstanding_work_t::tracked_t+      >::type+    >::type executor_type;    composed_work_guard(const Executor& ex)     : executor_(asio::prefer(ex, execution::outstanding_work.tracked))@@ -45,7 +48,7 @@   {   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return executor_;   }@@ -68,7 +71,7 @@   {   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return system_executor();   }@@ -78,10 +81,9 @@  template <typename Executor> struct composed_work_guard<Executor,-    enable_if_t<+    typename enable_if<       !execution::is_executor<Executor>::value-    >-  > : executor_work_guard<Executor>+    >::type> : executor_work_guard<Executor> {   composed_work_guard(const Executor& ex)     : executor_work_guard<Executor>(ex)@@ -97,7 +99,7 @@ template <> struct composed_io_executors<void()> {-  composed_io_executors() noexcept+  composed_io_executors() ASIO_NOEXCEPT     : head_(system_executor())   {   }@@ -114,7 +116,7 @@ template <typename Head> struct composed_io_executors<void(Head)> {-  explicit composed_io_executors(const Head& ex) noexcept+  explicit composed_io_executors(const Head& ex) ASIO_NOEXCEPT     : head_(ex)   {   }@@ -130,11 +132,13 @@   return composed_io_executors<void(Head)>(head); } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Head, typename... Tail> struct composed_io_executors<void(Head, Tail...)> {   explicit composed_io_executors(const Head& head,-      const Tail&... tail) noexcept+      const Tail&... tail) ASIO_NOEXCEPT     : head_(head),       tail_(tail...)   {@@ -158,6 +162,45 @@   return composed_io_executors<void(Head, Tail...)>(head, tail...); } +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF(n) \+template <typename Head, ASIO_VARIADIC_TPARAMS(n)> \+struct composed_io_executors<void(Head, ASIO_VARIADIC_TARGS(n))> \+{ \+  explicit composed_io_executors(const Head& head, \+      ASIO_VARIADIC_CONSTREF_PARAMS(n)) ASIO_NOEXCEPT \+    : head_(head), \+      tail_(ASIO_VARIADIC_BYVAL_ARGS(n)) \+  { \+  } \+\+  void reset() \+  { \+    head_.reset(); \+    tail_.reset(); \+  } \+\+  typedef Head head_type; \+  Head head_; \+  composed_io_executors<void(ASIO_VARIADIC_TARGS(n))> tail_; \+}; \+\+template <typename Head, ASIO_VARIADIC_TPARAMS(n)> \+inline composed_io_executors<void(Head, ASIO_VARIADIC_TARGS(n))> \+make_composed_io_executors(const Head& head, \+    ASIO_VARIADIC_CONSTREF_PARAMS(n)) \+{ \+  return composed_io_executors< \+    void(Head, ASIO_VARIADIC_TARGS(n))>( \+      head, ASIO_VARIADIC_BYVAL_ARGS(n)); \+} \+/**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF)+#undef ASIO_PRIVATE_COMPOSED_IO_EXECUTORS_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename> struct composed_work; @@ -166,7 +209,7 @@ {   typedef composed_io_executors<void()> executors_type; -  composed_work(const executors_type&) noexcept+  composed_work(const executors_type&) ASIO_NOEXCEPT     : head_(system_executor())   {   }@@ -185,7 +228,7 @@ {   typedef composed_io_executors<void(Head)> executors_type; -  explicit composed_work(const executors_type& ex) noexcept+  explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT     : head_(ex.head_)   {   }@@ -199,12 +242,14 @@   composed_work_guard<Head> head_; }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Head, typename... Tail> struct composed_work<void(Head, Tail...)> {   typedef composed_io_executors<void(Head, Tail...)> executors_type; -  explicit composed_work(const executors_type& ex) noexcept+  explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT     : head_(ex.head_),       tail_(ex.tail_)   {@@ -221,25 +266,56 @@   composed_work<void(Tail...)> tail_; }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_COMPOSED_WORK_DEF(n) \+template <typename Head, ASIO_VARIADIC_TPARAMS(n)> \+struct composed_work<void(Head, ASIO_VARIADIC_TARGS(n))> \+{ \+  typedef composed_io_executors<void(Head, \+    ASIO_VARIADIC_TARGS(n))> executors_type; \+\+  explicit composed_work(const executors_type& ex) ASIO_NOEXCEPT \+    : head_(ex.head_), \+      tail_(ex.tail_) \+  { \+  } \+\+  void reset() \+  { \+    head_.reset(); \+    tail_.reset(); \+  } \+\+  typedef Head head_type; \+  composed_work_guard<Head> head_; \+  composed_work<void(ASIO_VARIADIC_TARGS(n))> tail_; \+}; \+/**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_COMPOSED_WORK_DEF)+#undef ASIO_PRIVATE_COMPOSED_WORK_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename IoObject> inline typename IoObject::executor_type get_composed_io_executor(IoObject& io_object,-    enable_if_t<+    typename enable_if<       !is_executor<IoObject>::value-    >* = 0,-    enable_if_t<+    >::type* = 0,+    typename enable_if<       !execution::is_executor<IoObject>::value-    >* = 0)+    >::type* = 0) {   return io_object.get_executor(); }  template <typename Executor> inline const Executor& get_composed_io_executor(const Executor& ex,-    enable_if_t<+    typename enable_if<       is_executor<Executor>::value         || execution::is_executor<Executor>::value-    >* = 0)+    >::type* = 0) {   return ex; }
link/modules/asio-standalone/asio/include/asio/detail/concurrency_hint.hpp view
@@ -2,7 +2,7 @@ // detail/concurrency_hint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/conditionally_enabled_event.hpp view
@@ -2,7 +2,7 @@ // detail/conditionally_enabled_event.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/conditionally_enabled_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/conditionally_enabled_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -70,14 +70,6 @@     {       if (mutex_.enabled_ && !locked_)       {-        for (int n = mutex_.spin_count_; n != 0; n -= (n > 0) ? 1 : 0)-        {-          if (mutex_.mutex_.try_lock())-          {-            locked_ = true;-            return;-          }-        }         mutex_.mutex_.lock();         locked_ = true;       }@@ -112,9 +104,8 @@   };    // Constructor.-  explicit conditionally_enabled_mutex(bool enabled, int spin_count = 0)-    : spin_count_(spin_count),-      enabled_(enabled)+  explicit conditionally_enabled_mutex(bool enabled)+    : enabled_(enabled)   {   } @@ -129,22 +120,11 @@     return enabled_;   } -  // Get the spin count.-  int spin_count() const-  {-    return spin_count_;-  }-   // Lock the mutex.   void lock()   {     if (enabled_)-    {-      for (int n = spin_count_; n != 0; n -= (n > 0) ? 1 : 0)-        if (mutex_.try_lock())-          return;       mutex_.lock();-    }   }    // Unlock the mutex.@@ -158,7 +138,6 @@   friend class scoped_lock;   friend class conditionally_enabled_event;   asio::detail::mutex mutex_;-  const int spin_count_;   const bool enabled_; }; 
link/modules/asio-standalone/asio/include/asio/detail/config.hpp view
@@ -2,1429 +2,2307 @@ // detail/config.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DETAIL_CONFIG_HPP-#define ASIO_DETAIL_CONFIG_HPP--// boostify: non-boost code starts here-#if !defined(ASIO_STANDALONE)-# if !defined(ASIO_ENABLE_BOOST)-#  if (__cplusplus >= 201103)-#   define ASIO_STANDALONE 1-#  elif defined(_MSC_VER) && defined(_MSVC_LANG)-#   if (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)-#    define ASIO_STANDALONE 1-#   endif // (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)-#  endif // defined(_MSC_VER) && defined(_MSVC_LANG)-# endif // !defined(ASIO_ENABLE_BOOST)-#endif // !defined(ASIO_STANDALONE)--// Make standard library feature macros available.-#if defined(__has_include)-# if __has_include(<version>)-#  include <version>-# else // __has_include(<version>)-#  include <cstddef>-# endif // __has_include(<version>)-#else // defined(__has_include)-# include <cstddef>-#endif // defined(__has_include)--// boostify: non-boost code ends here-#if defined(ASIO_STANDALONE)-# define ASIO_DISABLE_BOOST_ALIGN 1-# define ASIO_DISABLE_BOOST_ARRAY 1-# define ASIO_DISABLE_BOOST_ASSERT 1-# define ASIO_DISABLE_BOOST_BIND 1-# define ASIO_DISABLE_BOOST_CHRONO 1-# define ASIO_DISABLE_BOOST_DATE_TIME 1-# define ASIO_DISABLE_BOOST_LIMITS 1-# define ASIO_DISABLE_BOOST_REGEX 1-# define ASIO_DISABLE_BOOST_STATIC_CONSTANT 1-# define ASIO_DISABLE_BOOST_THROW_EXCEPTION 1-# define ASIO_DISABLE_BOOST_WORKAROUND 1-#else // defined(ASIO_STANDALONE)-// Boost.Config library is available.-# include <boost/config.hpp>-# include <boost/version.hpp>-# define ASIO_HAS_BOOST_CONFIG 1-#endif // defined(ASIO_STANDALONE)--// Default to a header-only implementation. The user must specifically request-// separate compilation by defining either ASIO_SEPARATE_COMPILATION or-// ASIO_DYN_LINK (as a DLL/shared library implies separate compilation).-#if !defined(ASIO_HEADER_ONLY)-# if !defined(ASIO_SEPARATE_COMPILATION)-#  if !defined(ASIO_DYN_LINK)-#   define ASIO_HEADER_ONLY 1-#  endif // !defined(ASIO_DYN_LINK)-# endif // !defined(ASIO_SEPARATE_COMPILATION)-#endif // !defined(ASIO_HEADER_ONLY)--#if defined(ASIO_HEADER_ONLY)-# define ASIO_DECL inline-#else // defined(ASIO_HEADER_ONLY)-# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)-// We need to import/export our code only if the user has specifically asked-// for it by defining ASIO_DYN_LINK.-#  if defined(ASIO_DYN_LINK)-// Export if this is our own source, otherwise import.-#   if defined(ASIO_SOURCE)-#    define ASIO_DECL __declspec(dllexport)-#   else // defined(ASIO_SOURCE)-#    define ASIO_DECL __declspec(dllimport)-#   endif // defined(ASIO_SOURCE)-#  endif // defined(ASIO_DYN_LINK)-# endif // defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)-#endif // defined(ASIO_HEADER_ONLY)--// If ASIO_DECL isn't defined yet define it now.-#if !defined(ASIO_DECL)-# define ASIO_DECL-#endif // !defined(ASIO_DECL)--// Helper macro for documentation.-#define ASIO_UNSPECIFIED(e) e--// Microsoft Visual C++ detection.-#if !defined(ASIO_MSVC)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)-#  define ASIO_MSVC BOOST_MSVC-# elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \-      || (!defined(__MWERKS__) && !defined(__EDG_VERSION__)))-#  define ASIO_MSVC _MSC_VER-# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)-#endif // !defined(ASIO_MSVC)--// Clang / libc++ detection.-#if defined(__clang__)-# if (__cplusplus >= 201103)-#  if __has_include(<__config>)-#   include <__config>-#   if defined(_LIBCPP_VERSION)-#    define ASIO_HAS_CLANG_LIBCXX 1-#   endif // defined(_LIBCPP_VERSION)-#  endif // __has_include(<__config>)-# endif // (__cplusplus >= 201103)-#endif // defined(__clang__)--// Android platform detection.-#if defined(__ANDROID__)-# include <android/api-level.h>-#endif // defined(__ANDROID__)--// Always enabled. Retained for backwards compatibility in user code.-#if !defined(ASIO_DISABLE_CXX11_MACROS)-# define ASIO_HAS_MOVE 1-# define ASIO_MOVE_ARG(type) type&&-# define ASIO_MOVE_ARG2(type1, type2) type1, type2&&-# define ASIO_NONDEDUCED_MOVE_ARG(type) type&-# define ASIO_MOVE_CAST(type) static_cast<type&&>-# define ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>-# define ASIO_MOVE_OR_LVALUE(type) static_cast<type&&>-# define ASIO_MOVE_OR_LVALUE_ARG(type) type&&-# define ASIO_MOVE_OR_LVALUE_TYPE(type) type-# define ASIO_DELETED = delete-# define ASIO_HAS_VARIADIC_TEMPLATES 1-# define ASIO_HAS_CONSTEXPR 1-# define ASIO_STATIC_CONSTEXPR(type, assignment) \-   static constexpr type assignment-# define ASIO_HAS_NOEXCEPT 1-# define ASIO_NOEXCEPT noexcept(true)-# define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)-# define ASIO_NOEXCEPT_IF(c) noexcept(c)-# define ASIO_HAS_DECLTYPE 1-# define ASIO_AUTO_RETURN_TYPE_PREFIX(t) auto-# define ASIO_AUTO_RETURN_TYPE_PREFIX2(t0, t1) auto-# define ASIO_AUTO_RETURN_TYPE_PREFIX3(t0, t1, t2) auto-# define ASIO_AUTO_RETURN_TYPE_SUFFIX(expr) -> decltype expr-# define ASIO_HAS_ALIAS_TEMPLATES 1-# define ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS 1-# define ASIO_HAS_ENUM_CLASS 1-# define ASIO_HAS_REF_QUALIFIED_FUNCTIONS 1-# define ASIO_LVALUE_REF_QUAL &-# define ASIO_RVALUE_REF_QUAL &&-# define ASIO_HAS_USER_DEFINED_LITERALS 1-# define ASIO_HAS_ALIGNOF 1-# define ASIO_ALIGNOF(T) alignof(T)-# define ASIO_HAS_STD_ALIGN 1-# define ASIO_HAS_STD_SYSTEM_ERROR 1-# define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)-# define ASIO_HAS_STD_ARRAY 1-# define ASIO_HAS_STD_SHARED_PTR 1-# define ASIO_HAS_STD_ALLOCATOR_ARG 1-# define ASIO_HAS_STD_ATOMIC 1-# define ASIO_HAS_STD_CHRONO 1-# define ASIO_HAS_STD_ADDRESSOF 1-# define ASIO_HAS_STD_FUNCTION 1-# define ASIO_HAS_STD_REFERENCE_WRAPPER 1-# define ASIO_HAS_STD_TYPE_TRAITS 1-# define ASIO_HAS_NULLPTR 1-# define ASIO_HAS_CXX11_ALLOCATORS 1-# define ASIO_HAS_CSTDINT 1-# define ASIO_HAS_STD_THREAD 1-# define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1-# define ASIO_HAS_STD_CALL_ONCE 1-# define ASIO_HAS_STD_FUTURE 1-# define ASIO_HAS_STD_TUPLE 1-# define ASIO_HAS_STD_IOSTREAM_MOVE 1-# define ASIO_HAS_STD_EXCEPTION_PTR 1-# define ASIO_HAS_STD_NESTED_EXCEPTION 1-# define ASIO_HAS_STD_HASH 1-#endif // !defined(ASIO_DISABLE_CXX11_MACROS)--// Support for static constexpr with default initialisation.-#if !defined(ASIO_STATIC_CONSTEXPR_DEFAULT_INIT)-# if defined(__GNUC__)-#  if (__GNUC__ >= 8)-#   define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \-     static constexpr const type name{}-#  else // (__GNUC__ >= 8)-#   define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \-     static const type name-#  endif // (__GNUC__ >= 8)-# elif defined(ASIO_MSVC)-#  define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \-    static const type name-# else // defined(ASIO_MSVC)-#  define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \-    static constexpr const type name{}-# endif // defined(ASIO_MSVC)-#endif // !defined(ASIO_STATIC_CONSTEXPR_DEFAULT_INIT)--// Support noexcept on function types on compilers known to allow it.-#if !defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)-# if !defined(ASIO_DISABLE_NOEXCEPT_FUNCTION_TYPE)-#  if defined(__clang__)-#   if (__cplusplus >= 202002)-#    define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1-#   endif // (__cplusplus >= 202002)-#  elif defined(__GNUC__)-#   if (__cplusplus >= 202002)-#    define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1-#   endif // (__cplusplus >= 202002)-#  elif defined(ASIO_MSVC)-#   if (_MSC_VER >= 1900 && _MSVC_LANG >= 202002)-#    define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1-#   endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 202002)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_NOEXCEPT_FUNCTION_TYPE)-#endif // !defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)--// Support return type deduction on compilers known to allow it.-#if !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)-# if !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION)-#  if defined(__clang__)-#   if __has_feature(__cxx_return_type_deduction__)-#    define ASIO_HAS_RETURN_TYPE_DEDUCTION 1-#   endif // __has_feature(__cxx_return_type_deduction__)-#  elif (__cplusplus >= 201402)-#   define ASIO_HAS_RETURN_TYPE_DEDUCTION 1-#  elif defined(__cpp_return_type_deduction)-#   if (__cpp_return_type_deduction >= 201304)-#    define ASIO_HAS_RETURN_TYPE_DEDUCTION 1-#   endif // (__cpp_return_type_deduction >= 201304)-#  elif defined(ASIO_MSVC)-#   if (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)-#    define ASIO_HAS_RETURN_TYPE_DEDUCTION 1-#   endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION)-#endif // !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)--// Support concepts on compilers known to allow them.-#if !defined(ASIO_HAS_CONCEPTS)-# if !defined(ASIO_DISABLE_CONCEPTS)-#  if defined(__cpp_concepts)-#   define ASIO_HAS_CONCEPTS 1-#   if (__cpp_concepts >= 201707)-#    define ASIO_CONCEPT concept-#   else // (__cpp_concepts >= 201707)-#    define ASIO_CONCEPT concept bool-#   endif // (__cpp_concepts >= 201707)-#  endif // defined(__cpp_concepts)-# endif // !defined(ASIO_DISABLE_CONCEPTS)-#endif // !defined(ASIO_HAS_CONCEPTS)--// Support concepts on compilers known to allow them.-#if !defined(ASIO_HAS_STD_CONCEPTS)-# if !defined(ASIO_DISABLE_STD_CONCEPTS)-#  if defined(ASIO_HAS_CONCEPTS)-#   if (__cpp_lib_concepts >= 202002L)-#    define ASIO_HAS_STD_CONCEPTS 1-#   endif // (__cpp_concepts >= 202002L)-#  endif // defined(ASIO_HAS_CONCEPTS)-# endif // !defined(ASIO_DISABLE_STD_CONCEPTS)-#endif // !defined(ASIO_HAS_STD_CONCEPTS)--// Support template variables on compilers known to allow it.-#if !defined(ASIO_HAS_VARIABLE_TEMPLATES)-# if !defined(ASIO_DISABLE_VARIABLE_TEMPLATES)-#  if defined(__clang__)-#   if (__cplusplus >= 201402)-#    if __has_feature(__cxx_variable_templates__)-#     define ASIO_HAS_VARIABLE_TEMPLATES 1-#    endif // __has_feature(__cxx_variable_templates__)-#   endif // (__cplusplus >= 201402)-#  elif defined(__GNUC__) && !defined(__INTEL_COMPILER)-#   if (__GNUC__ >= 6)-#    if (__cplusplus >= 201402)-#     define ASIO_HAS_VARIABLE_TEMPLATES 1-#    endif // (__cplusplus >= 201402)-#   endif // (__GNUC__ >= 6)-#  endif // defined(__GNUC__) && !defined(__INTEL_COMPILER)-#  if defined(ASIO_MSVC)-#   if (_MSC_VER >= 1901)-#    define ASIO_HAS_VARIABLE_TEMPLATES 1-#   endif // (_MSC_VER >= 1901)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_VARIABLE_TEMPLATES)-#endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)--// Support SFINAEd template variables on compilers known to allow it.-#if !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)-# if !defined(ASIO_DISABLE_SFINAE_VARIABLE_TEMPLATES)-#  if defined(__clang__)-#   if (__cplusplus >= 201703)-#    if __has_feature(__cxx_variable_templates__)-#     define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1-#    endif // __has_feature(__cxx_variable_templates__)-#   endif // (__cplusplus >= 201703)-#  elif defined(__GNUC__)-#   if ((__GNUC__ == 8) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 8)-#    if (__cplusplus >= 201402)-#     define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1-#    endif // (__cplusplus >= 201402)-#   endif // ((__GNUC__ == 8) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 8)-#  endif // defined(__GNUC__)-#  if defined(ASIO_MSVC)-#   if (_MSC_VER >= 1901)-#    define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1-#   endif // (_MSC_VER >= 1901)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_SFINAE_VARIABLE_TEMPLATES)-#endif // !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)--// Support SFINAE use of constant expressions on compilers known to allow it.-#if !defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)-# if !defined(ASIO_DISABLE_CONSTANT_EXPRESSION_SFINAE)-#  if defined(__clang__)-#   if (__cplusplus >= 201402)-#    define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1-#   endif // (__cplusplus >= 201402)-#  elif defined(__GNUC__) && !defined(__INTEL_COMPILER)-#   if (__GNUC__ >= 7)-#    if (__cplusplus >= 201402)-#     define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1-#    endif // (__cplusplus >= 201402)-#   endif // (__GNUC__ >= 7)-#  endif // defined(__GNUC__) && !defined(__INTEL_COMPILER)-#  if defined(ASIO_MSVC)-#   if (_MSC_VER >= 1901)-#    define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1-#   endif // (_MSC_VER >= 1901)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_CONSTANT_EXPRESSION_SFINAE)-#endif // !defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)--// Enable workarounds for lack of working expression SFINAE.-#if !defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)-# if !defined(ASIO_DISABLE_WORKING_EXPRESSION_SFINAE)-#  if !defined(ASIO_MSVC) && !defined(__INTEL_COMPILER)-#   if (__cplusplus >= 201103)-#    define ASIO_HAS_WORKING_EXPRESSION_SFINAE 1-#   endif // (__cplusplus >= 201103)-#  elif defined(ASIO_MSVC) && (_MSC_VER >= 1929)-#   if (_MSVC_LANG >= 202000)-#    define ASIO_HAS_WORKING_EXPRESSION_SFINAE 1-#   endif // (_MSVC_LANG >= 202000)-#  endif // defined(ASIO_MSVC) && (_MSC_VER >= 1929)-# endif // !defined(ASIO_DISABLE_WORKING_EXPRESSION_SFINAE)-#endif // !defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)--// Support for capturing parameter packs in lambdas.-#if !defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)-# if !defined(ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)-#  if defined(__GNUC__)-#   if (__GNUC__ >= 6)-#    define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1-#   endif // (__GNUC__ >= 6)-#  elif defined(ASIO_MSVC)-#   if (_MSVC_LANG >= 201103)-#    define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1-#   endif // (_MSC_LANG >= 201103)-#  else // defined(ASIO_MSVC)-#   if (__cplusplus >= 201103)-#    define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1-#   endif // (__cplusplus >= 201103)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)-#endif // !defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)--// Support for inline variables.-#if !defined(ASIO_HAS_INLINE_VARIABLES)-# if !defined(ASIO_DISABLE_INLINE_VARIABLES)-#  if (__cplusplus >= 201703) && (__cpp_inline_variables >= 201606)-#   define ASIO_HAS_INLINE_VARIABLES 1-#   define ASIO_INLINE_VARIABLE inline-#  endif // (__cplusplus >= 201703) && (__cpp_inline_variables >= 201606)-# endif // !defined(ASIO_DISABLE_INLINE_VARIABLES)-#endif // !defined(ASIO_HAS_INLINE_VARIABLES)-#if !defined(ASIO_INLINE_VARIABLE)-# define ASIO_INLINE_VARIABLE-#endif // !defined(ASIO_INLINE_VARIABLE)--// Default alignment.-#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)-# define ASIO_DEFAULT_ALIGN __STDCPP_DEFAULT_NEW_ALIGNMENT__-#elif defined(__GNUC__)-# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-#  define ASIO_DEFAULT_ALIGN alignof(std::max_align_t)-# else // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-#  define ASIO_DEFAULT_ALIGN alignof(max_align_t)-# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-#else // defined(__GNUC__)-# define ASIO_DEFAULT_ALIGN alignof(std::max_align_t)-#endif // defined(__GNUC__)--// Standard library support for aligned allocation.-#if !defined(ASIO_HAS_STD_ALIGNED_ALLOC)-# if !defined(ASIO_DISABLE_STD_ALIGNED_ALLOC)-#  if (__cplusplus >= 201703)-#   if defined(__clang__)-#    if defined(ASIO_HAS_CLANG_LIBCXX)-#     if (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC) \-        && !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)-#      if defined(__ANDROID__) && (__ANDROID_API__ >= 28)-#        define ASIO_HAS_STD_ALIGNED_ALLOC 1-#      elif defined(__APPLE__)-#       if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)-#        if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)-#         define ASIO_HAS_STD_ALIGNED_ALLOC 1-#        endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)-#       elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)-#        if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)-#         define ASIO_HAS_STD_ALIGNED_ALLOC 1-#        endif // (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)-#       elif defined(__TV_OS_VERSION_MIN_REQUIRED)-#        if (__TV_OS_VERSION_MIN_REQUIRED >= 130000)-#         define ASIO_HAS_STD_ALIGNED_ALLOC 1-#        endif // (__TV_OS_VERSION_MIN_REQUIRED >= 130000)-#       elif defined(__WATCH_OS_VERSION_MIN_REQUIRED)-#        if (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)-#         define ASIO_HAS_STD_ALIGNED_ALLOC 1-#        endif // (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)-#       endif // defined(__WATCH_OS_X_VERSION_MIN_REQUIRED)-#      else // defined(__APPLE__)-#       define ASIO_HAS_STD_ALIGNED_ALLOC 1-#      endif // defined(__APPLE__)-#     endif // (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC)-            //   && !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)-#    elif defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)-#     define ASIO_HAS_STD_ALIGNED_ALLOC 1-#    endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)-#   elif defined(__GNUC__)-#    if ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)-#     if defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)-#      define ASIO_HAS_STD_ALIGNED_ALLOC 1-#     endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)-#    endif // ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)-#   endif // defined(__GNUC__)-#  endif // (__cplusplus >= 201703)-# endif // !defined(ASIO_DISABLE_STD_ALIGNED_ALLOC)-#endif // !defined(ASIO_HAS_STD_ALIGNED_ALLOC)--// Boost support for chrono.-#if !defined(ASIO_HAS_BOOST_CHRONO)-# if !defined(ASIO_DISABLE_BOOST_CHRONO)-#  if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)-#   define ASIO_HAS_BOOST_CHRONO 1-#  endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)-# endif // !defined(ASIO_DISABLE_BOOST_CHRONO)-#endif // !defined(ASIO_HAS_BOOST_CHRONO)--// Some form of chrono library is available.-#if !defined(ASIO_HAS_CHRONO)-# if defined(ASIO_HAS_STD_CHRONO) \-    || defined(ASIO_HAS_BOOST_CHRONO)-#  define ASIO_HAS_CHRONO 1-# endif // defined(ASIO_HAS_STD_CHRONO)-        // || defined(ASIO_HAS_BOOST_CHRONO)-#endif // !defined(ASIO_HAS_CHRONO)--// Boost support for the DateTime library.-#if !defined(ASIO_HAS_BOOST_DATE_TIME)-# if !defined(ASIO_DISABLE_BOOST_DATE_TIME)-#  define ASIO_HAS_BOOST_DATE_TIME 1-# endif // !defined(ASIO_DISABLE_BOOST_DATE_TIME)-#endif // !defined(ASIO_HAS_BOOST_DATE_TIME)--// Boost support for the Context library's fibers.-#if !defined(ASIO_HAS_BOOST_CONTEXT_FIBER)-# if !defined(ASIO_DISABLE_BOOST_CONTEXT_FIBER)-#  if defined(__clang__)-#   if (__cplusplus >= 201103)-#    define ASIO_HAS_BOOST_CONTEXT_FIBER 1-#   endif // (__cplusplus >= 201103)-#  elif defined(__GNUC__)-#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)-#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)-#     define ASIO_HAS_BOOST_CONTEXT_FIBER 1-#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)-#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)-#  endif // defined(__GNUC__)-#  if defined(ASIO_MSVC)-#   if (_MSVC_LANG >= 201103)-#    define ASIO_HAS_BOOST_CONTEXT_FIBER 1-#   endif // (_MSC_LANG >= 201103)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_BOOST_CONTEXT_FIBER)-#endif // !defined(ASIO_HAS_BOOST_CONTEXT_FIBER)--// Standard library support for std::string_view.-#if !defined(ASIO_HAS_STD_STRING_VIEW)-# if !defined(ASIO_DISABLE_STD_STRING_VIEW)-#  if defined(__clang__)-#   if defined(ASIO_HAS_CLANG_LIBCXX)-#    if (__cplusplus >= 201402)-#     if __has_include(<string_view>)-#      define ASIO_HAS_STD_STRING_VIEW 1-#     endif // __has_include(<string_view>)-#    endif // (__cplusplus >= 201402)-#   else // defined(ASIO_HAS_CLANG_LIBCXX)-#    if (__cplusplus >= 201703)-#     if __has_include(<string_view>)-#      define ASIO_HAS_STD_STRING_VIEW 1-#     endif // __has_include(<string_view>)-#    endif // (__cplusplus >= 201703)-#   endif // defined(ASIO_HAS_CLANG_LIBCXX)-#  elif defined(__GNUC__)-#   if (__GNUC__ >= 7)-#    if (__cplusplus >= 201703)-#     define ASIO_HAS_STD_STRING_VIEW 1-#    endif // (__cplusplus >= 201703)-#   endif // (__GNUC__ >= 7)-#  elif defined(ASIO_MSVC)-#   if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)-#    define ASIO_HAS_STD_STRING_VIEW 1-#   endif // (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_STRING_VIEW)-#endif // !defined(ASIO_HAS_STD_STRING_VIEW)--// Standard library support for std::experimental::string_view.-#if !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)-# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)-#  if defined(__clang__)-#   if defined(ASIO_HAS_CLANG_LIBCXX)-#    if (_LIBCPP_VERSION < 7000)-#     if (__cplusplus >= 201402)-#      if __has_include(<experimental/string_view>)-#       define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1-#      endif // __has_include(<experimental/string_view>)-#     endif // (__cplusplus >= 201402)-#    endif // (_LIBCPP_VERSION < 7000)-#   else // defined(ASIO_HAS_CLANG_LIBCXX)-#    if (__cplusplus >= 201402)-#     if __has_include(<experimental/string_view>)-#      define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1-#     endif // __has_include(<experimental/string_view>)-#    endif // (__cplusplus >= 201402)-#   endif // // defined(ASIO_HAS_CLANG_LIBCXX)-#  elif defined(__GNUC__)-#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-#    if (__cplusplus >= 201402)-#     define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1-#    endif // (__cplusplus >= 201402)-#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)-#  endif // defined(__GNUC__)-# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)-#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)--// Standard library has a string_view that we can use.-#if !defined(ASIO_HAS_STRING_VIEW)-# if !defined(ASIO_DISABLE_STRING_VIEW)-#  if defined(ASIO_HAS_STD_STRING_VIEW)-#   define ASIO_HAS_STRING_VIEW 1-#  elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)-#   define ASIO_HAS_STRING_VIEW 1-#  endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)-# endif // !defined(ASIO_DISABLE_STRING_VIEW)-#endif // !defined(ASIO_HAS_STRING_VIEW)--// Standard library has invoke_result (which supersedes result_of).-#if !defined(ASIO_HAS_STD_INVOKE_RESULT)-# if !defined(ASIO_DISABLE_STD_INVOKE_RESULT)-#  if defined(ASIO_MSVC)-#   if (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)-#    define ASIO_HAS_STD_INVOKE_RESULT 1-#   endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)-#  else // defined(ASIO_MSVC)-#   if (__cplusplus >= 201703) && (__cpp_lib_is_invocable >= 201703)-#    define ASIO_HAS_STD_INVOKE_RESULT 1-#   endif // (__cplusplus >= 201703) && (__cpp_lib_is_invocable >= 201703)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_INVOKE_RESULT)-#endif // !defined(ASIO_HAS_STD_INVOKE_RESULT)--// Standard library support for std::any.-#if !defined(ASIO_HAS_STD_ANY)-# if !defined(ASIO_DISABLE_STD_ANY)-#  if defined(__clang__)-#   if (__cplusplus >= 201703)-#    if __has_include(<any>)-#     define ASIO_HAS_STD_ANY 1-#    endif // __has_include(<any>)-#   endif // (__cplusplus >= 201703)-#  elif defined(__GNUC__)-#   if (__GNUC__ >= 7)-#    if (__cplusplus >= 201703)-#     define ASIO_HAS_STD_ANY 1-#    endif // (__cplusplus >= 201703)-#   endif // (__GNUC__ >= 7)-#  endif // defined(__GNUC__)-#  if defined(ASIO_MSVC)-#   if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)-#    define ASIO_HAS_STD_ANY 1-#   endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_ANY)-#endif // !defined(ASIO_HAS_STD_ANY)--// Standard library support for std::variant.-#if !defined(ASIO_HAS_STD_VARIANT)-# if !defined(ASIO_DISABLE_STD_VARIANT)-#  if defined(__clang__)-#   if (__cplusplus >= 201703)-#    if __has_include(<variant>)-#     define ASIO_HAS_STD_VARIANT 1-#    endif // __has_include(<variant>)-#   endif // (__cplusplus >= 201703)-#  elif defined(__GNUC__)-#   if (__GNUC__ >= 7)-#    if (__cplusplus >= 201703)-#     define ASIO_HAS_STD_VARIANT 1-#    endif // (__cplusplus >= 201703)-#   endif // (__GNUC__ >= 7)-#  endif // defined(__GNUC__)-#  if defined(ASIO_MSVC)-#   if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)-#    define ASIO_HAS_STD_VARIANT 1-#   endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_VARIANT)-#endif // !defined(ASIO_HAS_STD_VARIANT)--// Standard library support for std::source_location.-#if !defined(ASIO_HAS_STD_SOURCE_LOCATION)-# if !defined(ASIO_DISABLE_STD_SOURCE_LOCATION)-// ...-# endif // !defined(ASIO_DISABLE_STD_SOURCE_LOCATION)-#endif // !defined(ASIO_HAS_STD_SOURCE_LOCATION)--// Standard library support for std::experimental::source_location.-#if !defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)-# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_SOURCE_LOCATION)-#  if defined(__GNUC__)-#   if (__cplusplus >= 201709)-#    if __has_include(<experimental/source_location>)-#     define ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION 1-#    endif // __has_include(<experimental/source_location>)-#   endif // (__cplusplus >= 201709)-#  endif // defined(__GNUC__)-# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_SOURCE_LOCATION)-#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)--// Standard library has a source_location that we can use.-#if !defined(ASIO_HAS_SOURCE_LOCATION)-# if !defined(ASIO_DISABLE_SOURCE_LOCATION)-#  if defined(ASIO_HAS_STD_SOURCE_LOCATION)-#   define ASIO_HAS_SOURCE_LOCATION 1-#  elif defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)-#   define ASIO_HAS_SOURCE_LOCATION 1-#  endif // defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)-# endif // !defined(ASIO_DISABLE_SOURCE_LOCATION)-#endif // !defined(ASIO_HAS_SOURCE_LOCATION)--// Boost support for source_location and system errors.-#if !defined(ASIO_HAS_BOOST_SOURCE_LOCATION)-# if !defined(ASIO_DISABLE_BOOST_SOURCE_LOCATION)-#  if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)-#   define ASIO_HAS_BOOST_SOURCE_LOCATION 1-#  endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)-# endif // !defined(ASIO_DISABLE_BOOST_SOURCE_LOCATION)-#endif // !defined(ASIO_HAS_BOOST_SOURCE_LOCATION)--// Helper macros for working with Boost source locations.-#if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)-# define ASIO_SOURCE_LOCATION_PARAM \-  , const boost::source_location& loc-# define ASIO_SOURCE_LOCATION_DEFAULTED_PARAM \-  , const boost::source_location& loc = BOOST_CURRENT_LOCATION-# define ASIO_SOURCE_LOCATION_ARG , loc-#else // if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)-# define ASIO_SOURCE_LOCATION_PARAM-# define ASIO_SOURCE_LOCATION_DEFAULTED_PARAM-# define ASIO_SOURCE_LOCATION_ARG-#endif // if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)--// Standard library support for std::index_sequence.-#if !defined(ASIO_HAS_STD_INDEX_SEQUENCE)-# if !defined(ASIO_DISABLE_STD_INDEX_SEQUENCE)-#  if defined(__clang__)-#   if (__cplusplus >= 201402)-#    define ASIO_HAS_STD_INDEX_SEQUENCE 1-#   endif // (__cplusplus >= 201402)-#  elif defined(__GNUC__)-#   if (__GNUC__ >= 7)-#    if (__cplusplus >= 201402)-#     define ASIO_HAS_STD_INDEX_SEQUENCE 1-#    endif // (__cplusplus >= 201402)-#   endif // (__GNUC__ >= 7)-#  endif // defined(__GNUC__)-#  if defined(ASIO_MSVC)-#   if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)-#    define ASIO_HAS_STD_INDEX_SEQUENCE 1-#   endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_INDEX_SEQUENCE)-#endif // !defined(ASIO_HAS_STD_INDEX_SEQUENCE)--// Windows App target. Windows but with a limited API.-#if !defined(ASIO_WINDOWS_APP)-# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)-#  include <winapifamily.h>-#  if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \-       || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)) \-   && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)-#   define ASIO_WINDOWS_APP 1-#  endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)-         // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)-# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)-#endif // !defined(ASIO_WINDOWS_APP)--// Legacy WinRT target. Windows App is preferred.-#if !defined(ASIO_WINDOWS_RUNTIME)-# if !defined(ASIO_WINDOWS_APP)-#  if defined(__cplusplus_winrt)-#   include <winapifamily.h>-#   if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \-    && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)-#    define ASIO_WINDOWS_RUNTIME 1-#   endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)-          // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)-#  endif // defined(__cplusplus_winrt)-# endif // !defined(ASIO_WINDOWS_APP)-#endif // !defined(ASIO_WINDOWS_RUNTIME)--// Windows target. Excludes WinRT but includes Windows App targets.-#if !defined(ASIO_WINDOWS)-# if !defined(ASIO_WINDOWS_RUNTIME)-#  if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)-#   define ASIO_WINDOWS 1-#  elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)-#   define ASIO_WINDOWS 1-#  elif defined(ASIO_WINDOWS_APP)-#   define ASIO_WINDOWS 1-#  endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)-# endif // !defined(ASIO_WINDOWS_RUNTIME)-#endif // !defined(ASIO_WINDOWS)--// Windows: target OS version.-#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)-#  if defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))-#   pragma message( \-  "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\-  "- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\-  "- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\-  "Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).")-#  else // defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))-#   warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.-#   warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line.-#   warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).-#  endif // defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))-#  define _WIN32_WINNT 0x0601-# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)-# if defined(_MSC_VER)-#  if defined(_WIN32) && !defined(WIN32)-#   if !defined(_WINSOCK2API_)-#    define WIN32 // Needed for correct types in winsock2.h-#   else // !defined(_WINSOCK2API_)-#    error Please define the macro WIN32 in your compiler options-#   endif // !defined(_WINSOCK2API_)-#  endif // defined(_WIN32) && !defined(WIN32)-# endif // defined(_MSC_VER)-# if defined(__BORLANDC__)-#  if defined(__WIN32__) && !defined(WIN32)-#   if !defined(_WINSOCK2API_)-#    define WIN32 // Needed for correct types in winsock2.h-#   else // !defined(_WINSOCK2API_)-#    error Please define the macro WIN32 in your compiler options-#   endif // !defined(_WINSOCK2API_)-#  endif // defined(__WIN32__) && !defined(WIN32)-# endif // defined(__BORLANDC__)-# if defined(__CYGWIN__)-#  if !defined(__USE_W32_SOCKETS)-#   error You must add -D__USE_W32_SOCKETS to your compiler options.-#  endif // !defined(__USE_W32_SOCKETS)-# endif // defined(__CYGWIN__)-#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)--// Windows: minimise header inclusion.-#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# if !defined(ASIO_NO_WIN32_LEAN_AND_MEAN)-#  if !defined(WIN32_LEAN_AND_MEAN)-#   define WIN32_LEAN_AND_MEAN-#  endif // !defined(WIN32_LEAN_AND_MEAN)-# endif // !defined(ASIO_NO_WIN32_LEAN_AND_MEAN)-#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)--// Windows: suppress definition of "min" and "max" macros.-#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# if !defined(ASIO_NO_NOMINMAX)-#  if !defined(NOMINMAX)-#   define NOMINMAX 1-#  endif // !defined(NOMINMAX)-# endif // !defined(ASIO_NO_NOMINMAX)-#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)--// Windows: IO Completion Ports.-#if !defined(ASIO_HAS_IOCP)-# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-#  if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)-#   if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)-#    if !defined(ASIO_DISABLE_IOCP)-#     define ASIO_HAS_IOCP 1-#    endif // !defined(ASIO_DISABLE_IOCP)-#   endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)-#  endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)-# endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)-#endif // !defined(ASIO_HAS_IOCP)--// On POSIX (and POSIX-like) platforms we need to include unistd.h in order to-// get access to the various platform feature macros, e.g. to be able to test-// for threads support.-#if !defined(ASIO_HAS_UNISTD_H)-# if !defined(ASIO_HAS_BOOST_CONFIG)-#  if defined(unix) \-   || defined(__unix) \-   || defined(_XOPEN_SOURCE) \-   || defined(_POSIX_SOURCE) \-   || (defined(__MACH__) && defined(__APPLE__)) \-   || defined(__FreeBSD__) \-   || defined(__NetBSD__) \-   || defined(__OpenBSD__) \-   || defined(__linux__) \-   || defined(__HAIKU__)-#   define ASIO_HAS_UNISTD_H 1-#  endif-# endif // !defined(ASIO_HAS_BOOST_CONFIG)-#endif // !defined(ASIO_HAS_UNISTD_H)-#if defined(ASIO_HAS_UNISTD_H)-# include <unistd.h>-#endif // defined(ASIO_HAS_UNISTD_H)--// Linux: epoll, eventfd, timerfd and io_uring.-#if defined(__linux__)-# include <linux/version.h>-# if !defined(ASIO_HAS_EPOLL)-#  if !defined(ASIO_DISABLE_EPOLL)-#   if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)-#    define ASIO_HAS_EPOLL 1-#   endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)-#  endif // !defined(ASIO_DISABLE_EPOLL)-# endif // !defined(ASIO_HAS_EPOLL)-# if !defined(ASIO_HAS_EVENTFD)-#  if !defined(ASIO_DISABLE_EVENTFD)-#   if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)-#    define ASIO_HAS_EVENTFD 1-#   endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)-#  endif // !defined(ASIO_DISABLE_EVENTFD)-# endif // !defined(ASIO_HAS_EVENTFD)-# if !defined(ASIO_HAS_TIMERFD)-#  if defined(ASIO_HAS_EPOLL)-#   if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)-#    define ASIO_HAS_TIMERFD 1-#   endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)-#  endif // defined(ASIO_HAS_EPOLL)-# endif // !defined(ASIO_HAS_TIMERFD)-# if defined(ASIO_HAS_IO_URING)-#  if LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)-#   error Linux kernel 5.10 or later is required to support io_uring-#  endif // LINUX_VERSION_CODE < KERNEL_VERSION(5,10,0)-# endif // defined(ASIO_HAS_IO_URING)-#endif // defined(__linux__)--// Linux: io_uring is used instead of epoll.-#if !defined(ASIO_HAS_IO_URING_AS_DEFAULT)-# if !defined(ASIO_HAS_EPOLL) && defined(ASIO_HAS_IO_URING)-#  define ASIO_HAS_IO_URING_AS_DEFAULT 1-# endif // !defined(ASIO_HAS_EPOLL) && defined(ASIO_HAS_IO_URING)-#endif // !defined(ASIO_HAS_IO_URING_AS_DEFAULT)--// Mac OS X, FreeBSD, NetBSD, OpenBSD: kqueue.-#if (defined(__MACH__) && defined(__APPLE__)) \-  || defined(__FreeBSD__) \-  || defined(__NetBSD__) \-  || defined(__OpenBSD__)-# if !defined(ASIO_HAS_KQUEUE)-#  if !defined(ASIO_DISABLE_KQUEUE)-#   define ASIO_HAS_KQUEUE 1-#  endif // !defined(ASIO_DISABLE_KQUEUE)-# endif // !defined(ASIO_HAS_KQUEUE)-#endif // (defined(__MACH__) && defined(__APPLE__))-       //   || defined(__FreeBSD__)-       //   || defined(__NetBSD__)-       //   || defined(__OpenBSD__)--// Solaris: /dev/poll.-#if defined(__sun)-# if !defined(ASIO_HAS_DEV_POLL)-#  if !defined(ASIO_DISABLE_DEV_POLL)-#   define ASIO_HAS_DEV_POLL 1-#  endif // !defined(ASIO_DISABLE_DEV_POLL)-# endif // !defined(ASIO_HAS_DEV_POLL)-#endif // defined(__sun)--// Serial ports.-#if !defined(ASIO_HAS_SERIAL_PORT)-# if defined(ASIO_HAS_IOCP) \-  || !defined(ASIO_WINDOWS) \-  && !defined(ASIO_WINDOWS_RUNTIME) \-  && !defined(__CYGWIN__)-#  if !defined(__SYMBIAN32__)-#   if !defined(ASIO_DISABLE_SERIAL_PORT)-#    define ASIO_HAS_SERIAL_PORT 1-#   endif // !defined(ASIO_DISABLE_SERIAL_PORT)-#  endif // !defined(__SYMBIAN32__)-# endif // defined(ASIO_HAS_IOCP)-        //   || !defined(ASIO_WINDOWS)-        //   && !defined(ASIO_WINDOWS_RUNTIME)-        //   && !defined(__CYGWIN__)-#endif // !defined(ASIO_HAS_SERIAL_PORT)--// Windows: stream handles.-#if !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)-# if !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE)-#  if defined(ASIO_HAS_IOCP)-#   define ASIO_HAS_WINDOWS_STREAM_HANDLE 1-#  endif // defined(ASIO_HAS_IOCP)-# endif // !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE)-#endif // !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)--// Windows: random access handles.-#if !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)-# if !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)-#  if defined(ASIO_HAS_IOCP)-#   define ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1-#  endif // defined(ASIO_HAS_IOCP)-# endif // !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)-#endif // !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)--// Windows: object handles.-#if !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)-# if !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)-#  if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-#   if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)-#    define ASIO_HAS_WINDOWS_OBJECT_HANDLE 1-#   endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)-#  endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)-# endif // !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)-#endif // !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)--// Windows: OVERLAPPED wrapper.-#if !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)-# if !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)-#  if defined(ASIO_HAS_IOCP)-#   define ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1-#  endif // defined(ASIO_HAS_IOCP)-# endif // !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)-#endif // !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)--// POSIX: stream-oriented file descriptors.-#if !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)-# if !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)-#  if !defined(ASIO_WINDOWS) \-  && !defined(ASIO_WINDOWS_RUNTIME) \-  && !defined(__CYGWIN__)-#   define ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1-#  endif // !defined(ASIO_WINDOWS)-         //   && !defined(ASIO_WINDOWS_RUNTIME)-         //   && !defined(__CYGWIN__)-# endif // !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)-#endif // !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)--// UNIX domain sockets.-#if !defined(ASIO_HAS_LOCAL_SOCKETS)-# if !defined(ASIO_DISABLE_LOCAL_SOCKETS)-#  if !defined(ASIO_WINDOWS_RUNTIME)-#   define ASIO_HAS_LOCAL_SOCKETS 1-#  endif // !defined(ASIO_WINDOWS_RUNTIME)-# endif // !defined(ASIO_DISABLE_LOCAL_SOCKETS)-#endif // !defined(ASIO_HAS_LOCAL_SOCKETS)--// Files.-#if !defined(ASIO_HAS_FILE)-# if !defined(ASIO_DISABLE_FILE)-#  if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)-#   define ASIO_HAS_FILE 1-#  elif defined(ASIO_HAS_IO_URING)-#   define ASIO_HAS_FILE 1-#  endif // defined(ASIO_HAS_IO_URING)-# endif // !defined(ASIO_DISABLE_FILE)-#endif // !defined(ASIO_HAS_FILE)--// Pipes.-#if !defined(ASIO_HAS_PIPE)-# if defined(ASIO_HAS_IOCP) \-  || !defined(ASIO_WINDOWS) \-  && !defined(ASIO_WINDOWS_RUNTIME) \-  && !defined(__CYGWIN__)-#  if !defined(__SYMBIAN32__)-#   if !defined(ASIO_DISABLE_PIPE)-#    define ASIO_HAS_PIPE 1-#   endif // !defined(ASIO_DISABLE_PIPE)-#  endif // !defined(__SYMBIAN32__)-# endif // defined(ASIO_HAS_IOCP)-        //   || !defined(ASIO_WINDOWS)-        //   && !defined(ASIO_WINDOWS_RUNTIME)-        //   && !defined(__CYGWIN__)-#endif // !defined(ASIO_HAS_PIPE)--// Can use sigaction() instead of signal().-#if !defined(ASIO_HAS_SIGACTION)-# if !defined(ASIO_DISABLE_SIGACTION)-#  if !defined(ASIO_WINDOWS) \-  && !defined(ASIO_WINDOWS_RUNTIME) \-  && !defined(__CYGWIN__)-#   define ASIO_HAS_SIGACTION 1-#  endif // !defined(ASIO_WINDOWS)-         //   && !defined(ASIO_WINDOWS_RUNTIME)-         //   && !defined(__CYGWIN__)-# endif // !defined(ASIO_DISABLE_SIGACTION)-#endif // !defined(ASIO_HAS_SIGACTION)--// Can use signal().-#if !defined(ASIO_HAS_SIGNAL)-# if !defined(ASIO_DISABLE_SIGNAL)-#  if !defined(UNDER_CE)-#   define ASIO_HAS_SIGNAL 1-#  endif // !defined(UNDER_CE)-# endif // !defined(ASIO_DISABLE_SIGNAL)-#endif // !defined(ASIO_HAS_SIGNAL)--// Can use getaddrinfo() and getnameinfo().-#if !defined(ASIO_HAS_GETADDRINFO)-# if !defined(ASIO_DISABLE_GETADDRINFO)-#  if defined(ASIO_WINDOWS) || defined(__CYGWIN__)-#   if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)-#    define ASIO_HAS_GETADDRINFO 1-#   elif defined(UNDER_CE)-#    define ASIO_HAS_GETADDRINFO 1-#   endif // defined(UNDER_CE)-#  elif defined(__MACH__) && defined(__APPLE__)-#   if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)-#    if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)-#     define ASIO_HAS_GETADDRINFO 1-#    endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)-#   else // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)-#    define ASIO_HAS_GETADDRINFO 1-#   endif // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)-#  else // defined(__MACH__) && defined(__APPLE__)-#   define ASIO_HAS_GETADDRINFO 1-#  endif // defined(__MACH__) && defined(__APPLE__)-# endif // !defined(ASIO_DISABLE_GETADDRINFO)-#endif // !defined(ASIO_HAS_GETADDRINFO)--// Whether standard iostreams are disabled.-#if !defined(ASIO_NO_IOSTREAM)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_IOSTREAM)-#  define ASIO_NO_IOSTREAM 1-# endif // !defined(BOOST_NO_IOSTREAM)-#endif // !defined(ASIO_NO_IOSTREAM)--// Whether exception handling is disabled.-#if !defined(ASIO_NO_EXCEPTIONS)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_EXCEPTIONS)-#  define ASIO_NO_EXCEPTIONS 1-# endif // !defined(BOOST_NO_EXCEPTIONS)-#endif // !defined(ASIO_NO_EXCEPTIONS)--// Whether the typeid operator is supported.-#if !defined(ASIO_NO_TYPEID)-# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_TYPEID)-#  define ASIO_NO_TYPEID 1-# endif // !defined(BOOST_NO_TYPEID)-#endif // !defined(ASIO_NO_TYPEID)--// Threads.-#if !defined(ASIO_HAS_THREADS)-# if !defined(ASIO_DISABLE_THREADS)-#  if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)-#   define ASIO_HAS_THREADS 1-#  elif defined(__GNUC__) && !defined(__MINGW32__) \-     && !defined(linux) && !defined(__linux) && !defined(__linux__)-#   define ASIO_HAS_THREADS 1-#  elif defined(_MT) || defined(__MT__)-#   define ASIO_HAS_THREADS 1-#  elif defined(_REENTRANT)-#   define ASIO_HAS_THREADS 1-#  elif defined(__APPLE__)-#   define ASIO_HAS_THREADS 1-#  elif defined(__HAIKU__)-#   define ASIO_HAS_THREADS 1-#  elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)-#   define ASIO_HAS_THREADS 1-#  elif defined(_PTHREADS)-#   define ASIO_HAS_THREADS 1-#  endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)-# endif // !defined(ASIO_DISABLE_THREADS)-#endif // !defined(ASIO_HAS_THREADS)--// POSIX threads.-#if !defined(ASIO_HAS_PTHREADS)-# if defined(ASIO_HAS_THREADS)-#  if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)-#   define ASIO_HAS_PTHREADS 1-#  elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)-#   define ASIO_HAS_PTHREADS 1-#  elif defined(__HAIKU__)-#   define ASIO_HAS_PTHREADS 1-#  endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)-# endif // defined(ASIO_HAS_THREADS)-#endif // !defined(ASIO_HAS_PTHREADS)--// Helper to prevent macro expansion.-#define ASIO_PREVENT_MACRO_SUBSTITUTION--// Helper to define in-class constants.-#if !defined(ASIO_STATIC_CONSTANT)-# if !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)-#  define ASIO_STATIC_CONSTANT(type, assignment) \-    BOOST_STATIC_CONSTANT(type, assignment)-# else // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)-#  define ASIO_STATIC_CONSTANT(type, assignment) \-    static const type assignment-# endif // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)-#endif // !defined(ASIO_STATIC_CONSTANT)--// Boost align library.-#if !defined(ASIO_HAS_BOOST_ALIGN)-# if !defined(ASIO_DISABLE_BOOST_ALIGN)-#  if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105600)-#   define ASIO_HAS_BOOST_ALIGN 1-#  endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105600)-# endif // !defined(ASIO_DISABLE_BOOST_ALIGN)-#endif // !defined(ASIO_HAS_BOOST_ALIGN)--// Boost array library.-#if !defined(ASIO_HAS_BOOST_ARRAY)-# if !defined(ASIO_DISABLE_BOOST_ARRAY)-#  define ASIO_HAS_BOOST_ARRAY 1-# endif // !defined(ASIO_DISABLE_BOOST_ARRAY)-#endif // !defined(ASIO_HAS_BOOST_ARRAY)--// Boost assert macro.-#if !defined(ASIO_HAS_BOOST_ASSERT)-# if !defined(ASIO_DISABLE_BOOST_ASSERT)-#  define ASIO_HAS_BOOST_ASSERT 1-# endif // !defined(ASIO_DISABLE_BOOST_ASSERT)-#endif // !defined(ASIO_HAS_BOOST_ASSERT)--// Boost limits header.-#if !defined(ASIO_HAS_BOOST_LIMITS)-# if !defined(ASIO_DISABLE_BOOST_LIMITS)-#  define ASIO_HAS_BOOST_LIMITS 1-# endif // !defined(ASIO_DISABLE_BOOST_LIMITS)-#endif // !defined(ASIO_HAS_BOOST_LIMITS)--// Boost throw_exception function.-#if !defined(ASIO_HAS_BOOST_THROW_EXCEPTION)-# if !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION)-#  define ASIO_HAS_BOOST_THROW_EXCEPTION 1-# endif // !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION)-#endif // !defined(ASIO_HAS_BOOST_THROW_EXCEPTION)--// Boost regex library.-#if !defined(ASIO_HAS_BOOST_REGEX)-# if !defined(ASIO_DISABLE_BOOST_REGEX)-#  define ASIO_HAS_BOOST_REGEX 1-# endif // !defined(ASIO_DISABLE_BOOST_REGEX)-#endif // !defined(ASIO_HAS_BOOST_REGEX)--// Boost bind function.-#if !defined(ASIO_HAS_BOOST_BIND)-# if !defined(ASIO_DISABLE_BOOST_BIND)-#  define ASIO_HAS_BOOST_BIND 1-# endif // !defined(ASIO_DISABLE_BOOST_BIND)-#endif // !defined(ASIO_HAS_BOOST_BIND)--// Boost's BOOST_WORKAROUND macro.-#if !defined(ASIO_HAS_BOOST_WORKAROUND)-# if !defined(ASIO_DISABLE_BOOST_WORKAROUND)-#  define ASIO_HAS_BOOST_WORKAROUND 1-# endif // !defined(ASIO_DISABLE_BOOST_WORKAROUND)-#endif // !defined(ASIO_HAS_BOOST_WORKAROUND)--// Microsoft Visual C++'s secure C runtime library.-#if !defined(ASIO_HAS_SECURE_RTL)-# if !defined(ASIO_DISABLE_SECURE_RTL)-#  if defined(ASIO_MSVC) \-    && (ASIO_MSVC >= 1400) \-    && !defined(UNDER_CE)-#   define ASIO_HAS_SECURE_RTL 1-#  endif // defined(ASIO_MSVC)-         // && (ASIO_MSVC >= 1400)-         // && !defined(UNDER_CE)-# endif // !defined(ASIO_DISABLE_SECURE_RTL)-#endif // !defined(ASIO_HAS_SECURE_RTL)--// Handler hooking. Disabled for ancient Borland C++ and gcc compilers.-#if !defined(ASIO_HAS_HANDLER_HOOKS)-# if !defined(ASIO_DISABLE_HANDLER_HOOKS)-#  if defined(__GNUC__)-#   if (__GNUC__ >= 3)-#    define ASIO_HAS_HANDLER_HOOKS 1-#   endif // (__GNUC__ >= 3)-#  elif !defined(__BORLANDC__) || defined(__clang__)-#   define ASIO_HAS_HANDLER_HOOKS 1-#  endif // !defined(__BORLANDC__) || defined(__clang__)-# endif // !defined(ASIO_DISABLE_HANDLER_HOOKS)-#endif // !defined(ASIO_HAS_HANDLER_HOOKS)--// Support for the __thread keyword extension, or equivalent.-#if !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)-# if defined(__linux__)-#  if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))-#   if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)-#    if !defined(__INTEL_COMPILER) && !defined(__ICL) \-       && !(defined(__clang__) && defined(__ANDROID__))-#     define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-#     define ASIO_THREAD_KEYWORD __thread-#    elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)-#     define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-#    endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)-           // && !(defined(__clang__) && defined(__ANDROID__))-#   endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)-#  endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))-# endif // defined(__linux__)-# if defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME)-#  if (_MSC_VER >= 1700)-#   define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-#   define ASIO_THREAD_KEYWORD __declspec(thread)-#  endif // (_MSC_VER >= 1700)-# endif // defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME)-# if defined(__APPLE__)-#  if defined(__clang__)-#   if defined(__apple_build_version__)-#    define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-#    define ASIO_THREAD_KEYWORD __thread-#   endif // defined(__apple_build_version__)-#  endif // defined(__clang__)-# endif // defined(__APPLE__)-# if !defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION)-#  if defined(ASIO_HAS_BOOST_CONFIG)-#   if !defined(BOOST_NO_CXX11_THREAD_LOCAL)-#    define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1-#    define ASIO_THREAD_KEYWORD thread_local-#   endif // !defined(BOOST_NO_CXX11_THREAD_LOCAL)-#  endif // defined(ASIO_HAS_BOOST_CONFIG)-# endif // !defined(ASIO_HAS_THREAD_KEYWORD_EXTENSION)-#endif // !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)-#if !defined(ASIO_THREAD_KEYWORD)-# define ASIO_THREAD_KEYWORD __thread-#endif // !defined(ASIO_THREAD_KEYWORD)--// Support for POSIX ssize_t typedef.-#if !defined(ASIO_DISABLE_SSIZE_T)-# if defined(__linux__) \-   || (defined(__MACH__) && defined(__APPLE__))-#  define ASIO_HAS_SSIZE_T 1-# endif // defined(__linux__)-        //   || (defined(__MACH__) && defined(__APPLE__))-#endif // !defined(ASIO_DISABLE_SSIZE_T)--// Helper macros to manage transition away from error_code return values.-#if defined(ASIO_NO_DEPRECATED)-# define ASIO_SYNC_OP_VOID void-# define ASIO_SYNC_OP_VOID_RETURN(e) return-#else // defined(ASIO_NO_DEPRECATED)-# define ASIO_SYNC_OP_VOID asio::error_code-# define ASIO_SYNC_OP_VOID_RETURN(e) return e-#endif // defined(ASIO_NO_DEPRECATED)--// Newer gcc, clang need special treatment to suppress unused typedef warnings.-#if defined(__clang__)-# if defined(__apple_build_version__)-#  if (__clang_major__ >= 7)-#   define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))-#  endif // (__clang_major__ >= 7)-# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \-    || (__clang_major__ > 3)-#  define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))-# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6))-        //   || (__clang_major__ > 3)-#elif defined(__GNUC__)-# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)-#  define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))-# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)-#endif // defined(__GNUC__)-#if !defined(ASIO_UNUSED_TYPEDEF)-# define ASIO_UNUSED_TYPEDEF-#endif // !defined(ASIO_UNUSED_TYPEDEF)--// Some versions of gcc generate spurious warnings about unused variables.-#if defined(__GNUC__)-# if (__GNUC__ >= 4)-#  define ASIO_UNUSED_VARIABLE __attribute__((__unused__))-# endif // (__GNUC__ >= 4)-#endif // defined(__GNUC__)-#if !defined(ASIO_UNUSED_VARIABLE)-# define ASIO_UNUSED_VARIABLE-#endif // !defined(ASIO_UNUSED_VARIABLE)--// Helper macro to tell the optimiser what may be assumed to be true.-#if defined(ASIO_MSVC)-# define ASIO_ASSUME(expr) __assume(expr)-#elif defined(__clang__)-# if __has_builtin(__builtin_assume)-#  define ASIO_ASSUME(expr) __builtin_assume(expr)-# endif // __has_builtin(__builtin_assume)-#elif defined(__GNUC__)-# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)-#  define ASIO_ASSUME(expr) if (expr) {} else { __builtin_unreachable(); }-# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)-#endif // defined(__GNUC__)-#if !defined(ASIO_ASSUME)-# define ASIO_ASSUME(expr) (void)0-#endif // !defined(ASIO_ASSUME)--// Support the co_await keyword on compilers known to allow it.-#if !defined(ASIO_HAS_CO_AWAIT)-# if !defined(ASIO_DISABLE_CO_AWAIT)-#  if (__cplusplus >= 202002) \-     && (__cpp_impl_coroutine >= 201902) && (__cpp_lib_coroutine >= 201902)-#   define ASIO_HAS_CO_AWAIT 1-#  elif defined(ASIO_MSVC)-#   if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705) && !defined(__clang__)-#    define ASIO_HAS_CO_AWAIT 1-#   elif (_MSC_FULL_VER >= 190023506)-#    if defined(_RESUMABLE_FUNCTIONS_SUPPORTED)-#     define ASIO_HAS_CO_AWAIT 1-#    endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)-#   endif // (_MSC_FULL_VER >= 190023506)-#  elif defined(__clang__)-#   if (__clang_major__ >= 14)-#    if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)-#     if __has_include(<coroutine>)-#      define ASIO_HAS_CO_AWAIT 1-#     endif // __has_include(<coroutine>)-#    elif (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)-#     if __has_include(<experimental/coroutine>)-#      define ASIO_HAS_CO_AWAIT 1-#     endif // __has_include(<experimental/coroutine>)-#    endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)-#   else // (__clang_major__ >= 14)-#    if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)-#     if __has_include(<experimental/coroutine>)-#      define ASIO_HAS_CO_AWAIT 1-#     endif // __has_include(<experimental/coroutine>)-#    endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)-#   endif // (__clang_major__ >= 14)-#  elif defined(__GNUC__)-#   if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)-#    if __has_include(<coroutine>)-#     define ASIO_HAS_CO_AWAIT 1-#    endif // __has_include(<coroutine>)-#   endif // (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)-#  endif // defined(__GNUC__)-# endif // !defined(ASIO_DISABLE_CO_AWAIT)-#endif // !defined(ASIO_HAS_CO_AWAIT)--// Standard library support for coroutines.-#if !defined(ASIO_HAS_STD_COROUTINE)-# if !defined(ASIO_DISABLE_STD_COROUTINE)-#  if defined(ASIO_MSVC)-#   if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)-#    define ASIO_HAS_STD_COROUTINE 1-#   endif // (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)-#  elif defined(__clang__)-#   if (__clang_major__ >= 14)-#    if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)-#     if __has_include(<coroutine>)-#      define ASIO_HAS_STD_COROUTINE 1-#     endif // __has_include(<coroutine>)-#    endif // (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)-#   endif // (__clang_major__ >= 14)-#  elif defined(__GNUC__)-#   if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)-#    if __has_include(<coroutine>)-#     define ASIO_HAS_STD_COROUTINE 1-#    endif // __has_include(<coroutine>)-#   endif // (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)-#  endif // defined(__GNUC__)-# endif // !defined(ASIO_DISABLE_STD_COROUTINE)-#endif // !defined(ASIO_HAS_STD_COROUTINE)--// Compiler support for the the [[nodiscard]] attribute.-#if !defined(ASIO_NODISCARD)-# if defined(__has_cpp_attribute)-#  if __has_cpp_attribute(nodiscard)-#   if (__cplusplus >= 201703)-#    define ASIO_NODISCARD [[nodiscard]]-#   endif // (__cplusplus >= 201703)-#  endif // __has_cpp_attribute(nodiscard)-# endif // defined(__has_cpp_attribute)-#endif // !defined(ASIO_NODISCARD)-#if !defined(ASIO_NODISCARD)-# define ASIO_NODISCARD-#endif // !defined(ASIO_NODISCARD)--// Kernel support for MSG_NOSIGNAL.-#if !defined(ASIO_HAS_MSG_NOSIGNAL)-# if defined(__linux__)-#  define ASIO_HAS_MSG_NOSIGNAL 1-# elif defined(_POSIX_VERSION)-#  if (_POSIX_VERSION >= 200809L)-#   define ASIO_HAS_MSG_NOSIGNAL 1-#  endif // _POSIX_VERSION >= 200809L-# endif // defined(_POSIX_VERSION)-#endif // !defined(ASIO_HAS_MSG_NOSIGNAL)--// Standard library support for std::to_address.-#if !defined(ASIO_HAS_STD_TO_ADDRESS)-# if !defined(ASIO_DISABLE_STD_TO_ADDRESS)-#  if defined(__clang__)-#   if (__cplusplus >= 202002)-#    define ASIO_HAS_STD_TO_ADDRESS 1-#   endif // (__cplusplus >= 202002)-#  elif defined(__GNUC__)-#   if (__GNUC__ >= 8)-#    if (__cplusplus >= 202002)-#     define ASIO_HAS_STD_TO_ADDRESS 1-#    endif // (__cplusplus >= 202002)-#   endif // (__GNUC__ >= 8)-#  endif // defined(__GNUC__)-#  if defined(ASIO_MSVC)-#   if (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)-#    define ASIO_HAS_STD_TO_ADDRESS 1-#   endif // (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)-#  endif // defined(ASIO_MSVC)-# endif // !defined(ASIO_DISABLE_STD_TO_ADDRESS)-#endif // !defined(ASIO_HAS_STD_TO_ADDRESS)--// Standard library support for snprintf.-#if !defined(ASIO_HAS_SNPRINTF)-# if !defined(ASIO_DISABLE_SNPRINTF)-#  if defined(__APPLE__)-#   define ASIO_HAS_SNPRINTF 1-#  endif // defined(__APPLE__)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_CONFIG_HPP+#define ASIO_DETAIL_CONFIG_HPP++// boostify: non-boost code starts here+#if !defined(ASIO_STANDALONE)+# if !defined(ASIO_ENABLE_BOOST)+#  if (__cplusplus >= 201103)+#   define ASIO_STANDALONE 1+#  elif defined(_MSC_VER) && defined(_MSVC_LANG)+#   if (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)+#    define ASIO_STANDALONE 1+#   endif // (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)+#  endif // defined(_MSC_VER) && defined(_MSVC_LANG)+# endif // !defined(ASIO_ENABLE_BOOST)+#endif // !defined(ASIO_STANDALONE)++// Make standard library feature macros available.+#if defined(__has_include)+# if __has_include(<version>)+#  include <version>+# else // __has_include(<version>)+#  include <cstddef>+# endif // __has_include(<version>)+#else // defined(__has_include)+# include <cstddef>+#endif // defined(__has_include)++// boostify: non-boost code ends here+#if defined(ASIO_STANDALONE)+# define ASIO_DISABLE_BOOST_ALIGN 1+# define ASIO_DISABLE_BOOST_ARRAY 1+# define ASIO_DISABLE_BOOST_ASSERT 1+# define ASIO_DISABLE_BOOST_BIND 1+# define ASIO_DISABLE_BOOST_CHRONO 1+# define ASIO_DISABLE_BOOST_DATE_TIME 1+# define ASIO_DISABLE_BOOST_LIMITS 1+# define ASIO_DISABLE_BOOST_REGEX 1+# define ASIO_DISABLE_BOOST_STATIC_CONSTANT 1+# define ASIO_DISABLE_BOOST_THROW_EXCEPTION 1+# define ASIO_DISABLE_BOOST_WORKAROUND 1+#else // defined(ASIO_STANDALONE)+// Boost.Config library is available.+# include <boost/config.hpp>+# include <boost/version.hpp>+# define ASIO_HAS_BOOST_CONFIG 1+#endif // defined(ASIO_STANDALONE)++// Default to a header-only implementation. The user must specifically request+// separate compilation by defining either ASIO_SEPARATE_COMPILATION or+// ASIO_DYN_LINK (as a DLL/shared library implies separate compilation).+#if !defined(ASIO_HEADER_ONLY)+# if !defined(ASIO_SEPARATE_COMPILATION)+#  if !defined(ASIO_DYN_LINK)+#   define ASIO_HEADER_ONLY 1+#  endif // !defined(ASIO_DYN_LINK)+# endif // !defined(ASIO_SEPARATE_COMPILATION)+#endif // !defined(ASIO_HEADER_ONLY)++#if defined(ASIO_HEADER_ONLY)+# define ASIO_DECL inline+#else // defined(ASIO_HEADER_ONLY)+# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)+// We need to import/export our code only if the user has specifically asked+// for it by defining ASIO_DYN_LINK.+#  if defined(ASIO_DYN_LINK)+// Export if this is our own source, otherwise import.+#   if defined(ASIO_SOURCE)+#    define ASIO_DECL __declspec(dllexport)+#   else // defined(ASIO_SOURCE)+#    define ASIO_DECL __declspec(dllimport)+#   endif // defined(ASIO_SOURCE)+#  endif // defined(ASIO_DYN_LINK)+# endif // defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)+#endif // defined(ASIO_HEADER_ONLY)++// If ASIO_DECL isn't defined yet define it now.+#if !defined(ASIO_DECL)+# define ASIO_DECL+#endif // !defined(ASIO_DECL)++// Helper macro for documentation.+#define ASIO_UNSPECIFIED(e) e++// Microsoft Visual C++ detection.+#if !defined(ASIO_MSVC)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)+#  define ASIO_MSVC BOOST_MSVC+# elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \+      || (!defined(__MWERKS__) && !defined(__EDG_VERSION__)))+#  define ASIO_MSVC _MSC_VER+# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)+#endif // !defined(ASIO_MSVC)++// Clang / libc++ detection.+#if defined(__clang__)+# if (__cplusplus >= 201103)+#  if __has_include(<__config>)+#   include <__config>+#   if defined(_LIBCPP_VERSION)+#    define ASIO_HAS_CLANG_LIBCXX 1+#   endif // defined(_LIBCPP_VERSION)+#  endif // __has_include(<__config>)+# endif // (__cplusplus >= 201103)+#endif // defined(__clang__)++// Android platform detection.+#if defined(__ANDROID__)+# include <android/api-level.h>+#endif // defined(__ANDROID__)++// Support move construction and assignment on compilers known to allow it.+#if !defined(ASIO_HAS_MOVE)+# if !defined(ASIO_DISABLE_MOVE)+#  if defined(__clang__)+#   if __has_feature(__cxx_rvalue_references__)+#    define ASIO_HAS_MOVE 1+#   endif // __has_feature(__cxx_rvalue_references__)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_MOVE 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_MOVE 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+#  if defined(__INTEL_CXX11_MODE__)+#    if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)+#      define ASIO_HAS_MOVE 1+#    endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)+#    if defined(__ICL) && (__ICL >= 1500)+#      define ASIO_HAS_MOVE 1+#    endif // defined(__ICL) && (__ICL >= 1500)+#  endif // defined(__INTEL_CXX11_MODE__)+# endif // !defined(ASIO_DISABLE_MOVE)+#endif // !defined(ASIO_HAS_MOVE)++// If ASIO_MOVE_CAST isn't defined, and move support is available, define+// * ASIO_MOVE_ARG,+// * ASIO_NONDEDUCED_MOVE_ARG, and+// * ASIO_MOVE_CAST+// to take advantage of rvalue references and perfect forwarding.+#if defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)+# define ASIO_MOVE_ARG(type) type&&+# define ASIO_MOVE_ARG2(type1, type2) type1, type2&&+# define ASIO_NONDEDUCED_MOVE_ARG(type) type&+# define ASIO_MOVE_CAST(type) static_cast<type&&>+# define ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>+# define ASIO_MOVE_OR_LVALUE(type) static_cast<type&&>+# define ASIO_MOVE_OR_LVALUE_ARG(type) type&&+# define ASIO_MOVE_OR_LVALUE_TYPE(type) type+#endif // defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)++// If ASIO_MOVE_CAST still isn't defined, default to a C++03-compatible+// implementation. Note that older g++ and MSVC versions don't like it when you+// pass a non-member function through a const reference, so for most compilers+// we'll play it safe and stick with the old approach of passing the handler by+// value.+#if !defined(ASIO_MOVE_CAST)+# if defined(__GNUC__)+#  if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)+#   define ASIO_MOVE_ARG(type) const type&+#  else // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)+#   define ASIO_MOVE_ARG(type) type+#  endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)+# elif defined(ASIO_MSVC)+#  if (_MSC_VER >= 1400)+#   define ASIO_MOVE_ARG(type) const type&+#  else // (_MSC_VER >= 1400)+#   define ASIO_MOVE_ARG(type) type+#  endif // (_MSC_VER >= 1400)+# else+#  define ASIO_MOVE_ARG(type) type+# endif+# define ASIO_NONDEDUCED_MOVE_ARG(type) const type&+# define ASIO_MOVE_CAST(type) static_cast<const type&>+# define ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>+# define ASIO_MOVE_OR_LVALUE(type)+# define ASIO_MOVE_OR_LVALUE_ARG(type) type&+# define ASIO_MOVE_OR_LVALUE_TYPE(type) type&+#endif // !defined(ASIO_MOVE_CAST)++// Support variadic templates on compilers known to allow it.+#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)+# if !defined(ASIO_DISABLE_VARIADIC_TEMPLATES)+#  if defined(__clang__)+#   if __has_feature(__cxx_variadic_templates__)+#    define ASIO_HAS_VARIADIC_TEMPLATES 1+#   endif // __has_feature(__cxx_variadic_templates__)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_VARIADIC_TEMPLATES 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900)+#    define ASIO_HAS_VARIADIC_TEMPLATES 1+#   endif // (_MSC_VER >= 1900)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)+#if !defined(ASIO_ELLIPSIS)+# if defined(ASIO_HAS_VARIADIC_TEMPLATES)+#  define ASIO_ELLIPSIS ...+# else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#  define ASIO_ELLIPSIS+# endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_ELLIPSIS)++// Support deleted functions on compilers known to allow it.+#if !defined(ASIO_DELETED)+# if defined(__clang__)+#  if __has_feature(__cxx_deleted_functions__)+#   define ASIO_DELETED = delete+#  endif // __has_feature(__cxx_deleted_functions__)+# elif defined(__GNUC__)+#  if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#   if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#    define ASIO_DELETED = delete+#   endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#  endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# endif // defined(__GNUC__)+# if defined(ASIO_MSVC)+#  if (_MSC_VER >= 1900)+#   define ASIO_DELETED = delete+#  endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# if !defined(ASIO_DELETED)+#  define ASIO_DELETED+# endif // !defined(ASIO_DELETED)+#endif // !defined(ASIO_DELETED)++// Support constexpr on compilers known to allow it.+#if !defined(ASIO_HAS_CONSTEXPR)+# if !defined(ASIO_DISABLE_CONSTEXPR)+#  if defined(__clang__)+#   if __has_feature(__cxx_constexpr__)+#    define ASIO_HAS_CONSTEXPR 1+#   endif // __has_feature(__cxx_constexpr__)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_CONSTEXPR 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900)+#    define ASIO_HAS_CONSTEXPR 1+#   endif // (_MSC_VER >= 1900)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_CONSTEXPR)+#endif // !defined(ASIO_HAS_CONSTEXPR)+#if !defined(ASIO_CONSTEXPR)+# if defined(ASIO_HAS_CONSTEXPR)+#  define ASIO_CONSTEXPR constexpr+# else // defined(ASIO_HAS_CONSTEXPR)+#  define ASIO_CONSTEXPR+# endif // defined(ASIO_HAS_CONSTEXPR)+#endif // !defined(ASIO_CONSTEXPR)+#if !defined(ASIO_STATIC_CONSTEXPR)+# if defined(ASIO_HAS_CONSTEXPR)+#  define ASIO_STATIC_CONSTEXPR(type, assignment) \+    static constexpr type assignment+# else // defined(ASIO_HAS_CONSTEXPR)+#  define ASIO_STATIC_CONSTEXPR(type, assignment) \+    static const type assignment+# endif // defined(ASIO_HAS_CONSTEXPR)+#endif // !defined(ASIO_STATIC_CONSTEXPR)+#if !defined(ASIO_STATIC_CONSTEXPR_DEFAULT_INIT)+# if defined(ASIO_HAS_CONSTEXPR)+#  if defined(__GNUC__)+#   if (__GNUC__ >= 8)+#    define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+      static constexpr const type name{}+#   else // (__GNUC__ >= 8)+#    define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+      static const type name+#   endif // (__GNUC__ >= 8)+#  elif defined(ASIO_MSVC)+#   define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+     static const type name+#  else // defined(ASIO_MSVC)+#   define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+     static constexpr const type name{}+#  endif // defined(ASIO_MSVC)+# else // defined(ASIO_HAS_CONSTEXPR)+#  define ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(type, name) \+    static const type name+# endif // defined(ASIO_HAS_CONSTEXPR)+#endif // !defined(ASIO_STATIC_CONSTEXPR_DEFAULT_INIT)++// Support noexcept on compilers known to allow it.+#if !defined(ASIO_HAS_NOEXCEPT)+# if !defined(ASIO_DISABLE_NOEXCEPT)+#  if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300)+#   if !defined(BOOST_NO_NOEXCEPT)+#    define ASIO_HAS_NOEXCEPT 1+#   endif // !defined(BOOST_NO_NOEXCEPT)+#   define ASIO_NOEXCEPT BOOST_NOEXCEPT+#   define ASIO_NOEXCEPT_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW+#   define ASIO_NOEXCEPT_IF(c) BOOST_NOEXCEPT_IF(c)+#  elif defined(__clang__)+#   if __has_feature(__cxx_noexcept__)+#    define ASIO_HAS_NOEXCEPT 1+#   endif // __has_feature(__cxx_noexcept__)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#      define ASIO_HAS_NOEXCEPT 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  elif defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900)+#    define ASIO_HAS_NOEXCEPT 1+#   endif // (_MSC_VER >= 1900)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_NOEXCEPT)+# if !defined(ASIO_NOEXCEPT)+# endif // !defined(ASIO_NOEXCEPT)+# if !defined(ASIO_NOEXCEPT_OR_NOTHROW)+# endif // !defined(ASIO_NOEXCEPT_OR_NOTHROW)+#endif // !defined(ASIO_HAS_NOEXCEPT)+#if !defined(ASIO_NOEXCEPT)+# if defined(ASIO_HAS_NOEXCEPT)+#  define ASIO_NOEXCEPT noexcept(true)+# else // defined(ASIO_HAS_NOEXCEPT)+#  define ASIO_NOEXCEPT+# endif // defined(ASIO_HAS_NOEXCEPT)+#endif // !defined(ASIO_NOEXCEPT)+#if !defined(ASIO_NOEXCEPT_OR_NOTHROW)+# if defined(ASIO_HAS_NOEXCEPT)+#  define ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)+# else // defined(ASIO_HAS_NOEXCEPT)+#  define ASIO_NOEXCEPT_OR_NOTHROW throw()+# endif // defined(ASIO_HAS_NOEXCEPT)+#endif // !defined(ASIO_NOEXCEPT_OR_NOTHROW)+#if !defined(ASIO_NOEXCEPT_IF)+# if defined(ASIO_HAS_NOEXCEPT)+#  define ASIO_NOEXCEPT_IF(c) noexcept(c)+# else // defined(ASIO_HAS_NOEXCEPT)+#  define ASIO_NOEXCEPT_IF(c)+# endif // defined(ASIO_HAS_NOEXCEPT)+#endif // !defined(ASIO_NOEXCEPT_IF)++// Support noexcept on function types on compilers known to allow it.+#if !defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# if !defined(ASIO_DISABLE_NOEXCEPT_FUNCTION_TYPE)+#  if defined(__clang__)+#   if (__cplusplus >= 202002)+#    define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1+#   endif // (__cplusplus >= 202002)+#  elif defined(__GNUC__)+#   if (__cplusplus >= 202002)+#    define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1+#   endif // (__cplusplus >= 202002)+#  elif defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900 && _MSVC_LANG >= 202002)+#    define ASIO_HAS_NOEXCEPT_FUNCTION_TYPE 1+#   endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 202002)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_NOEXCEPT_FUNCTION_TYPE)+#endif // !defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++// Support automatic type deduction on compilers known to support it.+#if !defined(ASIO_HAS_DECLTYPE)+# if !defined(ASIO_DISABLE_DECLTYPE)+#  if defined(__clang__)+#   if __has_feature(__cxx_decltype__)+#    define ASIO_HAS_DECLTYPE 1+#   endif // __has_feature(__cxx_decltype__)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_DECLTYPE 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1800)+#    define ASIO_HAS_DECLTYPE 1+#   endif // (_MSC_VER >= 1800)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_DECLTYPE)+#endif // !defined(ASIO_HAS_DECLTYPE)+#if defined(ASIO_HAS_DECLTYPE)+# define ASIO_AUTO_RETURN_TYPE_PREFIX(t) auto+# define ASIO_AUTO_RETURN_TYPE_PREFIX2(t0, t1) auto+# define ASIO_AUTO_RETURN_TYPE_PREFIX3(t0, t1, t2) auto+# define ASIO_AUTO_RETURN_TYPE_SUFFIX(expr) -> decltype expr+#else // defined(ASIO_HAS_DECLTYPE)+# define ASIO_AUTO_RETURN_TYPE_PREFIX(t) t+# define ASIO_AUTO_RETURN_TYPE_PREFIX2(t0, t1) t0, t1+# define ASIO_AUTO_RETURN_TYPE_PREFIX3(t0, t1, t2) t0, t1, t2+# define ASIO_AUTO_RETURN_TYPE_SUFFIX(expr)+#endif // defined(ASIO_HAS_DECLTYPE)++// Support alias templates on compilers known to allow it.+#if !defined(ASIO_HAS_ALIAS_TEMPLATES)+# if !defined(ASIO_DISABLE_ALIAS_TEMPLATES)+#  if defined(__clang__)+#   if __has_feature(__cxx_alias_templates__)+#    define ASIO_HAS_ALIAS_TEMPLATES 1+#   endif // __has_feature(__cxx_alias_templates__)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_ALIAS_TEMPLATES 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900)+#    define ASIO_HAS_ALIAS_TEMPLATES 1+#   endif // (_MSC_VER >= 1900)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_ALIAS_TEMPLATES)+#endif // !defined(ASIO_HAS_ALIAS_TEMPLATES)++// Support return type deduction on compilers known to allow it.+#if !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)+# if !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION)+#  if defined(__clang__)+#   if __has_feature(__cxx_return_type_deduction__)+#    define ASIO_HAS_RETURN_TYPE_DEDUCTION 1+#   endif // __has_feature(__cxx_return_type_deduction__)+#  elif (__cplusplus >= 201402)+#   define ASIO_HAS_RETURN_TYPE_DEDUCTION 1+#  elif defined(__cpp_return_type_deduction)+#   if (__cpp_return_type_deduction >= 201304)+#    define ASIO_HAS_RETURN_TYPE_DEDUCTION 1+#   endif // (__cpp_return_type_deduction >= 201304)+#  elif defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)+#    define ASIO_HAS_RETURN_TYPE_DEDUCTION 1+#   endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201402)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_RETURN_TYPE_DEDUCTION)+#endif // !defined(ASIO_HAS_RETURN_TYPE_DEDUCTION)++// Support default function template arguments on compilers known to allow it.+#if !defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)+# if !defined(ASIO_DISABLE_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)+#  if (__cplusplus >= 201103)+#   define ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS 1+#  elif defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+#    define ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS 1+#   endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)+#endif // !defined(ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)++// Support enum classes on compilers known to allow them.+#if !defined(ASIO_HAS_ENUM_CLASS)+# if !defined(ASIO_DISABLE_ENUM_CLASS)+#  if (__cplusplus >= 201103)+#   define ASIO_HAS_ENUM_CLASS 1+#  elif defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+#    define ASIO_HAS_ENUM_CLASS 1+#   endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_ENUM_CLASS)+#endif // !defined(ASIO_HAS_ENUM_CLASS)++// Support concepts on compilers known to allow them.+#if !defined(ASIO_HAS_CONCEPTS)+# if !defined(ASIO_DISABLE_CONCEPTS)+#  if defined(__cpp_concepts)+#   define ASIO_HAS_CONCEPTS 1+#   if (__cpp_concepts >= 201707)+#    define ASIO_CONCEPT concept+#   else // (__cpp_concepts >= 201707)+#    define ASIO_CONCEPT concept bool+#   endif // (__cpp_concepts >= 201707)+#  endif // defined(__cpp_concepts)+# endif // !defined(ASIO_DISABLE_CONCEPTS)+#endif // !defined(ASIO_HAS_CONCEPTS)++// Support concepts on compilers known to allow them.+#if !defined(ASIO_HAS_STD_CONCEPTS)+# if !defined(ASIO_DISABLE_STD_CONCEPTS)+#  if defined(ASIO_HAS_CONCEPTS)+#   if (__cpp_lib_concepts >= 202002L)+#    define ASIO_HAS_STD_CONCEPTS 1+#   endif // (__cpp_concepts >= 202002L)+#  endif // defined(ASIO_HAS_CONCEPTS)+# endif // !defined(ASIO_DISABLE_STD_CONCEPTS)+#endif // !defined(ASIO_HAS_STD_CONCEPTS)++// Support template variables on compilers known to allow it.+#if !defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if !defined(ASIO_DISABLE_VARIABLE_TEMPLATES)+#  if defined(__clang__)+#   if (__cplusplus >= 201402)+#    if __has_feature(__cxx_variable_templates__)+#     define ASIO_HAS_VARIABLE_TEMPLATES 1+#    endif // __has_feature(__cxx_variable_templates__)+#   endif // (__cplusplus >= 201402)+#  elif defined(__GNUC__) && !defined(__INTEL_COMPILER)+#   if (__GNUC__ >= 6)+#    if (__cplusplus >= 201402)+#     define ASIO_HAS_VARIABLE_TEMPLATES 1+#    endif // (__cplusplus >= 201402)+#   endif // (__GNUC__ >= 6)+#  endif // defined(__GNUC__) && !defined(__INTEL_COMPILER)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1901)+#    define ASIO_HAS_VARIABLE_TEMPLATES 1+#   endif // (_MSC_VER >= 1901)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_VARIABLE_TEMPLATES)+#endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)++// Support SFINAEd template variables on compilers known to allow it.+#if !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+# if !defined(ASIO_DISABLE_SFINAE_VARIABLE_TEMPLATES)+#  if defined(__clang__)+#   if (__cplusplus >= 201703)+#    if __has_feature(__cxx_variable_templates__)+#     define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1+#    endif // __has_feature(__cxx_variable_templates__)+#   endif // (__cplusplus >= 201703)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 8) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 8)+#    if (__cplusplus >= 201402)+#     define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1+#    endif // (__cplusplus >= 201402)+#   endif // ((__GNUC__ == 8) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 8)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1901)+#    define ASIO_HAS_SFINAE_VARIABLE_TEMPLATES 1+#   endif // (_MSC_VER >= 1901)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_SFINAE_VARIABLE_TEMPLATES)+#endif // !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++// Support SFINAE use of constant expressions on compilers known to allow it.+#if !defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)+# if !defined(ASIO_DISABLE_CONSTANT_EXPRESSION_SFINAE)+#  if defined(__clang__)+#   if (__cplusplus >= 201402)+#    define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1+#   endif // (__cplusplus >= 201402)+#  elif defined(__GNUC__) && !defined(__INTEL_COMPILER)+#   if (__GNUC__ >= 7)+#    if (__cplusplus >= 201402)+#     define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1+#    endif // (__cplusplus >= 201402)+#   endif // (__GNUC__ >= 7)+#  endif // defined(__GNUC__) && !defined(__INTEL_COMPILER)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1901)+#    define ASIO_HAS_CONSTANT_EXPRESSION_SFINAE 1+#   endif // (_MSC_VER >= 1901)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_CONSTANT_EXPRESSION_SFINAE)+#endif // !defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)++// Enable workarounds for lack of working expression SFINAE.+#if !defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# if !defined(ASIO_DISABLE_WORKING_EXPRESSION_SFINAE)+#  if !defined(ASIO_MSVC) && !defined(__INTEL_COMPILER)+#   if (__cplusplus >= 201103)+#    define ASIO_HAS_WORKING_EXPRESSION_SFINAE 1+#   endif // (__cplusplus >= 201103)+#  elif defined(ASIO_MSVC) && (_MSC_VER >= 1929)+#   if (_MSVC_LANG >= 202000)+#    define ASIO_HAS_WORKING_EXPRESSION_SFINAE 1+#   endif // (_MSVC_LANG >= 202000)+#  endif // defined(ASIO_MSVC) && (_MSC_VER >= 1929)+# endif // !defined(ASIO_DISABLE_WORKING_EXPRESSION_SFINAE)+#endif // !defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++// Support ref-qualified functions on compilers known to allow it.+#if !defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+# if !defined(ASIO_DISABLE_REF_QUALIFIED_FUNCTIONS)+#  if defined(__clang__)+#   if __has_feature(__cxx_reference_qualified_functions__)+#    define ASIO_HAS_REF_QUALIFIED_FUNCTIONS 1+#   endif // __has_feature(__cxx_reference_qualified_functions__)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_REF_QUALIFIED_FUNCTIONS 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900)+#    define ASIO_HAS_REF_QUALIFIED_FUNCTIONS 1+#   endif // (_MSC_VER >= 1900)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_REF_QUALIFIED_FUNCTIONS)+#endif // !defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+# if !defined(ASIO_LVALUE_REF_QUAL)+#  define ASIO_LVALUE_REF_QUAL &+# endif // !defined(ASIO_LVALUE_REF_QUAL)+# if !defined(ASIO_RVALUE_REF_QUAL)+#  define ASIO_RVALUE_REF_QUAL &&+# endif // !defined(ASIO_RVALUE_REF_QUAL)+#else // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+# if !defined(ASIO_LVALUE_REF_QUAL)+#  define ASIO_LVALUE_REF_QUAL+# endif // !defined(ASIO_LVALUE_REF_QUAL)+# if !defined(ASIO_RVALUE_REF_QUAL)+#  define ASIO_RVALUE_REF_QUAL+# endif // !defined(ASIO_RVALUE_REF_QUAL)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++// Support for capturing parameter packs in lambdas.+#if !defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)+# if !defined(ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)+#  if defined(__GNUC__)+#   if (__GNUC__ >= 6)+#    define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1+#   endif // (__GNUC__ >= 6)+#  elif defined(ASIO_MSVC)+#   if (_MSVC_LANG >= 201103)+#    define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1+#   endif // (_MSC_LANG >= 201103)+#  else // defined(ASIO_MSVC)+#   if (__cplusplus >= 201103)+#    define ASIO_HAS_VARIADIC_LAMBDA_CAPTURES 1+#   endif // (__cplusplus >= 201103)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_VARIADIC_LAMBDA_CAPTURES)+#endif // !defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)++// Support for the alignof operator.+#if !defined(ASIO_HAS_ALIGNOF)+# if !defined(ASIO_DISABLE_ALIGNOF)+#  if (__cplusplus >= 201103)+#   define ASIO_HAS_ALIGNOF 1+#  endif // (__cplusplus >= 201103)+# endif // !defined(ASIO_DISABLE_ALIGNOF)+#endif // !defined(ASIO_HAS_ALIGNOF)++#if defined(ASIO_HAS_ALIGNOF)+# define ASIO_ALIGNOF(T) alignof(T)+# if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)+#  define ASIO_DEFAULT_ALIGN __STDCPP_DEFAULT_NEW_ALIGNMENT__+# elif defined(__GNUC__)+#  if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+#   define ASIO_DEFAULT_ALIGN alignof(std::max_align_t)+#  else // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+#   define ASIO_DEFAULT_ALIGN alignof(max_align_t)+#  endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+# else // defined(__GNUC__)+#  define ASIO_DEFAULT_ALIGN alignof(std::max_align_t)+# endif // defined(__GNUC__)+#else // defined(ASIO_HAS_ALIGNOF)+# define ASIO_ALIGNOF(T) 1+# define ASIO_DEFAULT_ALIGN 1+#endif // defined(ASIO_HAS_ALIGNOF)++// Support for user-defined literals.+#if !defined(ASIO_HAS_USER_DEFINED_LITERALS)+# if !defined(ASIO_DISABLE_USER_DEFINED_LITERALS)+#  if (__cplusplus >= 201103)+#   define ASIO_HAS_USER_DEFINED_LITERALS 1+#  elif defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+#    define ASIO_HAS_USER_DEFINED_LITERALS 1+#   endif // (_MSC_VER >= 1900 && _MSVC_LANG >= 201103)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_USER_DEFINED_LITERALS)+#endif // !defined(ASIO_HAS_USER_DEFINED_LITERALS)++// Standard library support for aligned allocation.+#if !defined(ASIO_HAS_STD_ALIGNED_ALLOC)+# if !defined(ASIO_DISABLE_STD_ALIGNED_ALLOC)+#  if (__cplusplus >= 201703)+#   if defined(__clang__)+#    if defined(ASIO_HAS_CLANG_LIBCXX)+#     if (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC) \+        && !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)+#      if defined(__APPLE__)+#       if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)+#        if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)+#         define ASIO_HAS_STD_ALIGNED_ALLOC 1+#        endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)+#       elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)+#        if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)+#         define ASIO_HAS_STD_ALIGNED_ALLOC 1+#        endif // (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000)+#       elif defined(__TV_OS_VERSION_MIN_REQUIRED)+#        if (__TV_OS_VERSION_MIN_REQUIRED >= 130000)+#         define ASIO_HAS_STD_ALIGNED_ALLOC 1+#        endif // (__TV_OS_VERSION_MIN_REQUIRED >= 130000)+#       elif defined(__WATCH_OS_VERSION_MIN_REQUIRED)+#        if (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)+#         define ASIO_HAS_STD_ALIGNED_ALLOC 1+#        endif // (__WATCH_OS_VERSION_MIN_REQUIRED >= 60000)+#       endif // defined(__WATCH_OS_X_VERSION_MIN_REQUIRED)+#      else // defined(__APPLE__)+#       define ASIO_HAS_STD_ALIGNED_ALLOC 1+#      endif // defined(__APPLE__)+#     endif // (_LIBCPP_STD_VER > 14) && defined(_LIBCPP_HAS_ALIGNED_ALLOC)+            //   && !defined(_LIBCPP_MSVCRT) && !defined(__MINGW32__)+#    elif defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)+#     define ASIO_HAS_STD_ALIGNED_ALLOC 1+#    endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)+#   elif defined(__GNUC__)+#    if ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)+#     if defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)+#      define ASIO_HAS_STD_ALIGNED_ALLOC 1+#     endif // defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)+#    endif // ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 7)+#   endif // defined(__GNUC__)+#  endif // (__cplusplus >= 201703)+# endif // !defined(ASIO_DISABLE_STD_ALIGNED_ALLOC)+#endif // !defined(ASIO_HAS_STD_ALIGNED_ALLOC)++// Standard library support for std::align.+#if !defined(ASIO_HAS_STD_ALIGN)+# if !defined(ASIO_DISABLE_STD_ALIGN)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_ALIGN 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_STD_ALIGN 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if (__GNUC__ >= 6)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_ALIGN 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // (__GNUC__ >= 6)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_ALIGN 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ALIGN)+#endif // !defined(ASIO_HAS_STD_ALIGN)++// Standard library support for system errors.+#if !defined(ASIO_HAS_STD_SYSTEM_ERROR)+# if !defined(ASIO_DISABLE_STD_SYSTEM_ERROR)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_SYSTEM_ERROR 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<system_error>)+#     define ASIO_HAS_STD_SYSTEM_ERROR 1+#    endif // __has_include(<system_error>)+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_SYSTEM_ERROR 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_SYSTEM_ERROR 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_SYSTEM_ERROR)+#endif // !defined(ASIO_HAS_STD_SYSTEM_ERROR)++// Compliant C++11 compilers put noexcept specifiers on error_category members.+#if !defined(ASIO_ERROR_CATEGORY_NOEXCEPT)+# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300)+#  define ASIO_ERROR_CATEGORY_NOEXCEPT BOOST_NOEXCEPT+# elif defined(__clang__)+#  if __has_feature(__cxx_noexcept__)+#   define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)+#  endif // __has_feature(__cxx_noexcept__)+# elif defined(__GNUC__)+#  if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#   if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)+#   endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#  endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+# elif defined(ASIO_MSVC)+#  if (_MSC_VER >= 1900)+#   define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)+#  endif // (_MSC_VER >= 1900)+# endif // defined(ASIO_MSVC)+# if !defined(ASIO_ERROR_CATEGORY_NOEXCEPT)+#  define ASIO_ERROR_CATEGORY_NOEXCEPT+# endif // !defined(ASIO_ERROR_CATEGORY_NOEXCEPT)+#endif // !defined(ASIO_ERROR_CATEGORY_NOEXCEPT)++// Standard library support for arrays.+#if !defined(ASIO_HAS_STD_ARRAY)+# if !defined(ASIO_DISABLE_STD_ARRAY)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_ARRAY 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<array>)+#     define ASIO_HAS_STD_ARRAY 1+#    endif // __has_include(<array>)+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_ARRAY 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1600)+#    define ASIO_HAS_STD_ARRAY 1+#   endif // (_MSC_VER >= 1600)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ARRAY)+#endif // !defined(ASIO_HAS_STD_ARRAY)++// Standard library support for shared_ptr and weak_ptr.+#if !defined(ASIO_HAS_STD_SHARED_PTR)+# if !defined(ASIO_DISABLE_STD_SHARED_PTR)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_SHARED_PTR 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_STD_SHARED_PTR 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_SHARED_PTR 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1600)+#    define ASIO_HAS_STD_SHARED_PTR 1+#   endif // (_MSC_VER >= 1600)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_SHARED_PTR)+#endif // !defined(ASIO_HAS_STD_SHARED_PTR)++// Standard library support for allocator_arg_t.+#if !defined(ASIO_HAS_STD_ALLOCATOR_ARG)+# if !defined(ASIO_DISABLE_STD_ALLOCATOR_ARG)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_ALLOCATOR_ARG 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_STD_ALLOCATOR_ARG 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_ALLOCATOR_ARG 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1600)+#    define ASIO_HAS_STD_ALLOCATOR_ARG 1+#   endif // (_MSC_VER >= 1600)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ALLOCATOR_ARG)+#endif // !defined(ASIO_HAS_STD_ALLOCATOR_ARG)++// Standard library support for atomic operations.+#if !defined(ASIO_HAS_STD_ATOMIC)+# if !defined(ASIO_DISABLE_STD_ATOMIC)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_ATOMIC 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<atomic>)+#     define ASIO_HAS_STD_ATOMIC 1+#    endif // __has_include(<atomic>)+#   elif defined(__apple_build_version__) && defined(_LIBCPP_VERSION)+#    if (__clang_major__ >= 10)+#     if __has_include(<atomic>)+#      define ASIO_HAS_STD_ATOMIC 1+#     endif // __has_include(<atomic>)+#    endif // (__clang_major__ >= 10)+#   endif // defined(__apple_build_version__) && defined(_LIBCPP_VERSION)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_ATOMIC 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_ATOMIC 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ATOMIC)+#endif // !defined(ASIO_HAS_STD_ATOMIC)++// Standard library support for chrono. Some standard libraries (such as the+// libstdc++ shipped with gcc 4.6) provide monotonic_clock as per early C++0x+// drafts, rather than the eventually standardised name of steady_clock.+#if !defined(ASIO_HAS_STD_CHRONO)+# if !defined(ASIO_DISABLE_STD_CHRONO)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_CHRONO 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<chrono>)+#     define ASIO_HAS_STD_CHRONO 1+#    endif // __has_include(<chrono>)+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_CHRONO 1+#     if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6))+#      define ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK 1+#     endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6))+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_CHRONO 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_CHRONO)+#endif // !defined(ASIO_HAS_STD_CHRONO)++// Boost support for chrono.+#if !defined(ASIO_HAS_BOOST_CHRONO)+# if !defined(ASIO_DISABLE_BOOST_CHRONO)+#  if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)+#   define ASIO_HAS_BOOST_CHRONO 1+#  endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 104700)+# endif // !defined(ASIO_DISABLE_BOOST_CHRONO)+#endif // !defined(ASIO_HAS_BOOST_CHRONO)++// Some form of chrono library is available.+#if !defined(ASIO_HAS_CHRONO)+# if defined(ASIO_HAS_STD_CHRONO) \+    || defined(ASIO_HAS_BOOST_CHRONO)+#  define ASIO_HAS_CHRONO 1+# endif // defined(ASIO_HAS_STD_CHRONO)+        // || defined(ASIO_HAS_BOOST_CHRONO)+#endif // !defined(ASIO_HAS_CHRONO)++// Boost support for the DateTime library.+#if !defined(ASIO_HAS_BOOST_DATE_TIME)+# if !defined(ASIO_DISABLE_BOOST_DATE_TIME)+#  define ASIO_HAS_BOOST_DATE_TIME 1+# endif // !defined(ASIO_DISABLE_BOOST_DATE_TIME)+#endif // !defined(ASIO_HAS_BOOST_DATE_TIME)++// Boost support for the Coroutine library.+#if !defined(ASIO_HAS_BOOST_COROUTINE)+# if !defined(ASIO_DISABLE_BOOST_COROUTINE)+#  define ASIO_HAS_BOOST_COROUTINE 1+# endif // !defined(ASIO_DISABLE_BOOST_COROUTINE)+#endif // !defined(ASIO_HAS_BOOST_COROUTINE)++// Boost support for the Context library's fibers.+#if !defined(ASIO_HAS_BOOST_CONTEXT_FIBER)+# if !defined(ASIO_DISABLE_BOOST_CONTEXT_FIBER)+#  if defined(__clang__)+#   if (__cplusplus >= 201103)+#    define ASIO_HAS_BOOST_CONTEXT_FIBER 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_BOOST_CONTEXT_FIBER 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSVC_LANG >= 201103)+#    define ASIO_HAS_BOOST_CONTEXT_FIBER 1+#   endif // (_MSC_LANG >= 201103)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_BOOST_CONTEXT_FIBER)+#endif // !defined(ASIO_HAS_BOOST_CONTEXT_FIBER)++// Standard library support for addressof.+#if !defined(ASIO_HAS_STD_ADDRESSOF)+# if !defined(ASIO_DISABLE_STD_ADDRESSOF)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_ADDRESSOF 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_STD_ADDRESSOF 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_ADDRESSOF 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_ADDRESSOF 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ADDRESSOF)+#endif // !defined(ASIO_HAS_STD_ADDRESSOF)++// Standard library support for the function class.+#if !defined(ASIO_HAS_STD_FUNCTION)+# if !defined(ASIO_DISABLE_STD_FUNCTION)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_FUNCTION 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_STD_FUNCTION 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_FUNCTION 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_FUNCTION 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_FUNCTION)+#endif // !defined(ASIO_HAS_STD_FUNCTION)++// Standard library support for the reference_wrapper class.+#if !defined(ASIO_HAS_STD_REFERENCE_WRAPPER)+# if !defined(ASIO_DISABLE_STD_REFERENCE_WRAPPER)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_REFERENCE_WRAPPER 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_STD_REFERENCE_WRAPPER 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_REFERENCE_WRAPPER 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_REFERENCE_WRAPPER 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_REFERENCE_WRAPPER)+#endif // !defined(ASIO_HAS_STD_REFERENCE_WRAPPER)++// Standard library support for type traits.+#if !defined(ASIO_HAS_STD_TYPE_TRAITS)+# if !defined(ASIO_DISABLE_STD_TYPE_TRAITS)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_TYPE_TRAITS 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<type_traits>)+#     define ASIO_HAS_STD_TYPE_TRAITS 1+#    endif // __has_include(<type_traits>)+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_TYPE_TRAITS 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_TYPE_TRAITS 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_TYPE_TRAITS)+#endif // !defined(ASIO_HAS_STD_TYPE_TRAITS)++// Standard library support for the nullptr_t type.+#if !defined(ASIO_HAS_NULLPTR)+# if !defined(ASIO_DISABLE_NULLPTR)+#  if defined(__clang__)+#   if __has_feature(__cxx_nullptr__)+#    define ASIO_HAS_NULLPTR 1+#   endif // __has_feature(__cxx_nullptr__)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_NULLPTR 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_NULLPTR 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_NULLPTR)+#endif // !defined(ASIO_HAS_NULLPTR)++// Standard library support for the C++11 allocator additions.+#if !defined(ASIO_HAS_CXX11_ALLOCATORS)+# if !defined(ASIO_DISABLE_CXX11_ALLOCATORS)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_CXX11_ALLOCATORS 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_CXX11_ALLOCATORS 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_CXX11_ALLOCATORS 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1800)+#    define ASIO_HAS_CXX11_ALLOCATORS 1+#   endif // (_MSC_VER >= 1800)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_CXX11_ALLOCATORS)+#endif // !defined(ASIO_HAS_CXX11_ALLOCATORS)++// Standard library support for the cstdint header.+#if !defined(ASIO_HAS_CSTDINT)+# if !defined(ASIO_DISABLE_CSTDINT)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_CSTDINT 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_CSTDINT 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_CSTDINT 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_CSTDINT 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_CSTDINT)+#endif // !defined(ASIO_HAS_CSTDINT)++// Standard library support for the thread class.+#if !defined(ASIO_HAS_STD_THREAD)+# if !defined(ASIO_DISABLE_STD_THREAD)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_THREAD 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<thread>)+#     define ASIO_HAS_STD_THREAD 1+#    endif // __has_include(<thread>)+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_THREAD 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_THREAD 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_THREAD)+#endif // !defined(ASIO_HAS_STD_THREAD)++// Standard library support for the mutex and condition variable classes.+#if !defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+# if !defined(ASIO_DISABLE_STD_MUTEX_AND_CONDVAR)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<mutex>)+#     define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1+#    endif // __has_include(<mutex>)+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_MUTEX_AND_CONDVAR 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_MUTEX_AND_CONDVAR)+#endif // !defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)++// Standard library support for the call_once function.+#if !defined(ASIO_HAS_STD_CALL_ONCE)+# if !defined(ASIO_DISABLE_STD_CALL_ONCE)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_CALL_ONCE 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<mutex>)+#     define ASIO_HAS_STD_CALL_ONCE 1+#    endif // __has_include(<mutex>)+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_CALL_ONCE 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_CALL_ONCE 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_CALL_ONCE)+#endif // !defined(ASIO_HAS_STD_CALL_ONCE)++// Standard library support for futures.+#if !defined(ASIO_HAS_STD_FUTURE)+# if !defined(ASIO_DISABLE_STD_FUTURE)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_FUTURE 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<future>)+#     define ASIO_HAS_STD_FUTURE 1+#    endif // __has_include(<future>)+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_FUTURE 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_FUTURE 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_FUTURE)+#endif // !defined(ASIO_HAS_STD_FUTURE)++// Standard library support for std::tuple.+#if !defined(ASIO_HAS_STD_TUPLE)+# if !defined(ASIO_DISABLE_STD_TUPLE)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_TUPLE 1+#   elif (__cplusplus >= 201103)+#    if __has_include(<tuple>)+#     define ASIO_HAS_STD_TUPLE 1+#    endif // __has_include(<tuple>)+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_TUPLE 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_TUPLE 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_TUPLE)+#endif // !defined(ASIO_HAS_STD_TUPLE)++// Standard library support for std::string_view.+#if !defined(ASIO_HAS_STD_STRING_VIEW)+# if !defined(ASIO_DISABLE_STD_STRING_VIEW)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    if (__cplusplus >= 201402)+#     if __has_include(<string_view>)+#      define ASIO_HAS_STD_STRING_VIEW 1+#     endif // __has_include(<string_view>)+#    endif // (__cplusplus >= 201402)+#   else // defined(ASIO_HAS_CLANG_LIBCXX)+#    if (__cplusplus >= 201703)+#     if __has_include(<string_view>)+#      define ASIO_HAS_STD_STRING_VIEW 1+#     endif // __has_include(<string_view>)+#    endif // (__cplusplus >= 201703)+#   endif // defined(ASIO_HAS_CLANG_LIBCXX)+#  elif defined(__GNUC__)+#   if (__GNUC__ >= 7)+#    if (__cplusplus >= 201703)+#     define ASIO_HAS_STD_STRING_VIEW 1+#    endif // (__cplusplus >= 201703)+#   endif // (__GNUC__ >= 7)+#  elif defined(ASIO_MSVC)+#   if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)+#    define ASIO_HAS_STD_STRING_VIEW 1+#   endif // (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_STRING_VIEW)+#endif // !defined(ASIO_HAS_STD_STRING_VIEW)++// Standard library support for std::experimental::string_view.+#if !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)+# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    if (_LIBCPP_VERSION < 7000)+#     if (__cplusplus >= 201402)+#      if __has_include(<experimental/string_view>)+#       define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1+#      endif // __has_include(<experimental/string_view>)+#     endif // (__cplusplus >= 201402)+#    endif // (_LIBCPP_VERSION < 7000)+#   else // defined(ASIO_HAS_CLANG_LIBCXX)+#    if (__cplusplus >= 201402)+#     if __has_include(<experimental/string_view>)+#      define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1+#     endif // __has_include(<experimental/string_view>)+#    endif // (__cplusplus >= 201402)+#   endif // // defined(ASIO_HAS_CLANG_LIBCXX)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201402)+#     define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1+#    endif // (__cplusplus >= 201402)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)+#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)++// Standard library has a string_view that we can use.+#if !defined(ASIO_HAS_STRING_VIEW)+# if !defined(ASIO_DISABLE_STRING_VIEW)+#  if defined(ASIO_HAS_STD_STRING_VIEW)+#   define ASIO_HAS_STRING_VIEW 1+#  elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)+#   define ASIO_HAS_STRING_VIEW 1+#  endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)+# endif // !defined(ASIO_DISABLE_STRING_VIEW)+#endif // !defined(ASIO_HAS_STRING_VIEW)++// Standard library support for iostream move construction and assignment.+#if !defined(ASIO_HAS_STD_IOSTREAM_MOVE)+# if !defined(ASIO_DISABLE_STD_IOSTREAM_MOVE)+#  if defined(__clang__)+#   if (__cplusplus >= 201103)+#    define ASIO_HAS_STD_IOSTREAM_MOVE 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_IOSTREAM_MOVE 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // (__GNUC__ > 4)+#  elif defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_IOSTREAM_MOVE 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_IOSTREAM_MOVE)+#endif // !defined(ASIO_HAS_STD_IOSTREAM_MOVE)++// Standard library has invoke_result (which supersedes result_of).+#if !defined(ASIO_HAS_STD_INVOKE_RESULT)+# if !defined(ASIO_DISABLE_STD_INVOKE_RESULT)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)+#    define ASIO_HAS_STD_INVOKE_RESULT 1+#   endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)+#  else // defined(ASIO_MSVC)+#   if (__cplusplus >= 201703)+#    define ASIO_HAS_STD_INVOKE_RESULT 1+#   endif // (__cplusplus >= 201703)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_INVOKE_RESULT)+#endif // !defined(ASIO_HAS_STD_INVOKE_RESULT)++// Standard library support for std::exception_ptr and std::current_exception.+#if !defined(ASIO_HAS_STD_EXCEPTION_PTR)+# if !defined(ASIO_DISABLE_STD_EXCEPTION_PTR)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_EXCEPTION_PTR 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_STD_EXCEPTION_PTR 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_EXCEPTION_PTR 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1800)+#    define ASIO_HAS_STD_EXCEPTION_PTR 1+#   endif // (_MSC_VER >= 1800)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_EXCEPTION_PTR)+#endif // !defined(ASIO_HAS_STD_EXCEPTION_PTR)++// Standard library support for std::nested_exception.+#if !defined(ASIO_HAS_STD_NESTED_EXCEPTION)+# if !defined(ASIO_DISABLE_STD_NESTED_EXCEPTION)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_NESTED_EXCEPTION 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_STD_NESTED_EXCEPTION 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_NESTED_EXCEPTION 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1900)+#    define ASIO_HAS_STD_NESTED_EXCEPTION 1+#   endif // (_MSC_VER >= 1900)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_NESTED_EXCEPTION)+#endif // !defined(ASIO_HAS_STD_NESTED_EXCEPTION)++// Standard library support for std::any.+#if !defined(ASIO_HAS_STD_ANY)+# if !defined(ASIO_DISABLE_STD_ANY)+#  if defined(__clang__)+#   if (__cplusplus >= 201703)+#    if __has_include(<any>)+#     define ASIO_HAS_STD_ANY 1+#    endif // __has_include(<any>)+#   endif // (__cplusplus >= 201703)+#  elif defined(__GNUC__)+#   if (__GNUC__ >= 7)+#    if (__cplusplus >= 201703)+#     define ASIO_HAS_STD_ANY 1+#    endif // (__cplusplus >= 201703)+#   endif // (__GNUC__ >= 7)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)+#    define ASIO_HAS_STD_ANY 1+#   endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_ANY)+#endif // !defined(ASIO_HAS_STD_ANY)++// Standard library support for std::variant.+#if !defined(ASIO_HAS_STD_VARIANT)+# if !defined(ASIO_DISABLE_STD_VARIANT)+#  if defined(__clang__)+#   if (__cplusplus >= 201703)+#    if __has_include(<variant>)+#     define ASIO_HAS_STD_VARIANT 1+#    endif // __has_include(<variant>)+#   endif // (__cplusplus >= 201703)+#  elif defined(__GNUC__)+#   if (__GNUC__ >= 7)+#    if (__cplusplus >= 201703)+#     define ASIO_HAS_STD_VARIANT 1+#    endif // (__cplusplus >= 201703)+#   endif // (__GNUC__ >= 7)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)+#    define ASIO_HAS_STD_VARIANT 1+#   endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_VARIANT)+#endif // !defined(ASIO_HAS_STD_VARIANT)++// Standard library support for std::source_location.+#if !defined(ASIO_HAS_STD_SOURCE_LOCATION)+# if !defined(ASIO_DISABLE_STD_SOURCE_LOCATION)+// ...+# endif // !defined(ASIO_DISABLE_STD_SOURCE_LOCATION)+#endif // !defined(ASIO_HAS_STD_SOURCE_LOCATION)++// Standard library support for std::experimental::source_location.+#if !defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)+# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_SOURCE_LOCATION)+#  if defined(__GNUC__)+#   if (__cplusplus >= 201709)+#    if __has_include(<experimental/source_location>)+#     define ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION 1+#    endif // __has_include(<experimental/source_location>)+#   endif // (__cplusplus >= 201709)+#  endif // defined(__GNUC__)+# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_SOURCE_LOCATION)+#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)++// Standard library has a source_location that we can use.+#if !defined(ASIO_HAS_SOURCE_LOCATION)+# if !defined(ASIO_DISABLE_SOURCE_LOCATION)+#  if defined(ASIO_HAS_STD_SOURCE_LOCATION)+#   define ASIO_HAS_SOURCE_LOCATION 1+#  elif defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)+#   define ASIO_HAS_SOURCE_LOCATION 1+#  endif // defined(ASIO_HAS_STD_EXPERIMENTAL_SOURCE_LOCATION)+# endif // !defined(ASIO_DISABLE_SOURCE_LOCATION)+#endif // !defined(ASIO_HAS_SOURCE_LOCATION)++// Boost support for source_location and system errors.+#if !defined(ASIO_HAS_BOOST_SOURCE_LOCATION)+# if !defined(ASIO_DISABLE_BOOST_SOURCE_LOCATION)+#  if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)+#   define ASIO_HAS_BOOST_SOURCE_LOCATION 1+#  endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 107900)+# endif // !defined(ASIO_DISABLE_BOOST_SOURCE_LOCATION)+#endif // !defined(ASIO_HAS_BOOST_SOURCE_LOCATION)++// Helper macros for working with Boost source locations.+#if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)+# define ASIO_SOURCE_LOCATION_PARAM \+  , const boost::source_location& loc+# define ASIO_SOURCE_LOCATION_DEFAULTED_PARAM \+  , const boost::source_location& loc = BOOST_CURRENT_LOCATION+# define ASIO_SOURCE_LOCATION_ARG , loc+#else // if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)+# define ASIO_SOURCE_LOCATION_PARAM+# define ASIO_SOURCE_LOCATION_DEFAULTED_PARAM+# define ASIO_SOURCE_LOCATION_ARG+#endif // if defined(ASIO_HAS_BOOST_SOURCE_LOCATION)++// Standard library support for std::index_sequence.+#if !defined(ASIO_HAS_STD_INDEX_SEQUENCE)+# if !defined(ASIO_DISABLE_STD_INDEX_SEQUENCE)+#  if defined(__clang__)+#   if (__cplusplus >= 201402)+#    define ASIO_HAS_STD_INDEX_SEQUENCE 1+#   endif // (__cplusplus >= 201402)+#  elif defined(__GNUC__)+#   if (__GNUC__ >= 7)+#    if (__cplusplus >= 201402)+#     define ASIO_HAS_STD_INDEX_SEQUENCE 1+#    endif // (__cplusplus >= 201402)+#   endif // (__GNUC__ >= 7)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)+#    define ASIO_HAS_STD_INDEX_SEQUENCE 1+#   endif // (_MSC_VER >= 1910) && (_MSVC_LANG >= 201402)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_INDEX_SEQUENCE)+#endif // !defined(ASIO_HAS_STD_INDEX_SEQUENCE)++// Windows App target. Windows but with a limited API.+#if !defined(ASIO_WINDOWS_APP)+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)+#  include <winapifamily.h>+#  if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \+       || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)) \+   && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)+#   define ASIO_WINDOWS_APP 1+#  endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)+         // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)+# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)+#endif // !defined(ASIO_WINDOWS_APP)++// Legacy WinRT target. Windows App is preferred.+#if !defined(ASIO_WINDOWS_RUNTIME)+# if !defined(ASIO_WINDOWS_APP)+#  if defined(__cplusplus_winrt)+#   include <winapifamily.h>+#   if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \+    && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)+#    define ASIO_WINDOWS_RUNTIME 1+#   endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)+          // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)+#  endif // defined(__cplusplus_winrt)+# endif // !defined(ASIO_WINDOWS_APP)+#endif // !defined(ASIO_WINDOWS_RUNTIME)++// Windows target. Excludes WinRT but includes Windows App targets.+#if !defined(ASIO_WINDOWS)+# if !defined(ASIO_WINDOWS_RUNTIME)+#  if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)+#   define ASIO_WINDOWS 1+#  elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)+#   define ASIO_WINDOWS 1+#  elif defined(ASIO_WINDOWS_APP)+#   define ASIO_WINDOWS 1+#  endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)+# endif // !defined(ASIO_WINDOWS_RUNTIME)+#endif // !defined(ASIO_WINDOWS)++// Windows: target OS version.+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)+#  if defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))+#   pragma message( \+  "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\+  "- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\+  "- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\+  "Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).")+#  else // defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))+#   warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.+#   warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line.+#   warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).+#  endif // defined(_MSC_VER) || (defined(__BORLANDC__) && !defined(__clang__))+#  define _WIN32_WINNT 0x0601+# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)+# if defined(_MSC_VER)+#  if defined(_WIN32) && !defined(WIN32)+#   if !defined(_WINSOCK2API_)+#    define WIN32 // Needed for correct types in winsock2.h+#   else // !defined(_WINSOCK2API_)+#    error Please define the macro WIN32 in your compiler options+#   endif // !defined(_WINSOCK2API_)+#  endif // defined(_WIN32) && !defined(WIN32)+# endif // defined(_MSC_VER)+# if defined(__BORLANDC__)+#  if defined(__WIN32__) && !defined(WIN32)+#   if !defined(_WINSOCK2API_)+#    define WIN32 // Needed for correct types in winsock2.h+#   else // !defined(_WINSOCK2API_)+#    error Please define the macro WIN32 in your compiler options+#   endif // !defined(_WINSOCK2API_)+#  endif // defined(__WIN32__) && !defined(WIN32)+# endif // defined(__BORLANDC__)+# if defined(__CYGWIN__)+#  if !defined(__USE_W32_SOCKETS)+#   error You must add -D__USE_W32_SOCKETS to your compiler options.+#  endif // !defined(__USE_W32_SOCKETS)+# endif // defined(__CYGWIN__)+#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)++// Windows: minimise header inclusion.+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# if !defined(ASIO_NO_WIN32_LEAN_AND_MEAN)+#  if !defined(WIN32_LEAN_AND_MEAN)+#   define WIN32_LEAN_AND_MEAN+#  endif // !defined(WIN32_LEAN_AND_MEAN)+# endif // !defined(ASIO_NO_WIN32_LEAN_AND_MEAN)+#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)++// Windows: suppress definition of "min" and "max" macros.+#if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# if !defined(ASIO_NO_NOMINMAX)+#  if !defined(NOMINMAX)+#   define NOMINMAX 1+#  endif // !defined(NOMINMAX)+# endif // !defined(ASIO_NO_NOMINMAX)+#endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)++// Windows: IO Completion Ports.+#if !defined(ASIO_HAS_IOCP)+# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+#  if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)+#   if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)+#    if !defined(ASIO_DISABLE_IOCP)+#     define ASIO_HAS_IOCP 1+#    endif // !defined(ASIO_DISABLE_IOCP)+#   endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)+#  endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)+# endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)+#endif // !defined(ASIO_HAS_IOCP)++// On POSIX (and POSIX-like) platforms we need to include unistd.h in order to+// get access to the various platform feature macros, e.g. to be able to test+// for threads support.+#if !defined(ASIO_HAS_UNISTD_H)+# if !defined(ASIO_HAS_BOOST_CONFIG)+#  if defined(unix) \+   || defined(__unix) \+   || defined(_XOPEN_SOURCE) \+   || defined(_POSIX_SOURCE) \+   || (defined(__MACH__) && defined(__APPLE__)) \+   || defined(__FreeBSD__) \+   || defined(__NetBSD__) \+   || defined(__OpenBSD__) \+   || defined(__linux__) \+   || defined(__HAIKU__)+#   define ASIO_HAS_UNISTD_H 1+#  endif+# endif // !defined(ASIO_HAS_BOOST_CONFIG)+#endif // !defined(ASIO_HAS_UNISTD_H)+#if defined(ASIO_HAS_UNISTD_H)+# include <unistd.h>+#endif // defined(ASIO_HAS_UNISTD_H)++// Linux: epoll, eventfd and timerfd.+#if defined(__linux__)+# include <linux/version.h>+# if !defined(ASIO_HAS_EPOLL)+#  if !defined(ASIO_DISABLE_EPOLL)+#   if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)+#    define ASIO_HAS_EPOLL 1+#   endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)+#  endif // !defined(ASIO_DISABLE_EPOLL)+# endif // !defined(ASIO_HAS_EPOLL)+# if !defined(ASIO_HAS_EVENTFD)+#  if !defined(ASIO_DISABLE_EVENTFD)+#   if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)+#    define ASIO_HAS_EVENTFD 1+#   endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)+#  endif // !defined(ASIO_DISABLE_EVENTFD)+# endif // !defined(ASIO_HAS_EVENTFD)+# if !defined(ASIO_HAS_TIMERFD)+#  if defined(ASIO_HAS_EPOLL)+#   if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)+#    define ASIO_HAS_TIMERFD 1+#   endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)+#  endif // defined(ASIO_HAS_EPOLL)+# endif // !defined(ASIO_HAS_TIMERFD)+#endif // defined(__linux__)++// Linux: io_uring is used instead of epoll.+#if !defined(ASIO_HAS_IO_URING_AS_DEFAULT)+# if !defined(ASIO_HAS_EPOLL) && defined(ASIO_HAS_IO_URING)+#  define ASIO_HAS_IO_URING_AS_DEFAULT 1+# endif // !defined(ASIO_HAS_EPOLL) && defined(ASIO_HAS_IO_URING)+#endif // !defined(ASIO_HAS_IO_URING_AS_DEFAULT)++// Mac OS X, FreeBSD, NetBSD, OpenBSD: kqueue.+#if (defined(__MACH__) && defined(__APPLE__)) \+  || defined(__FreeBSD__) \+  || defined(__NetBSD__) \+  || defined(__OpenBSD__)+# if !defined(ASIO_HAS_KQUEUE)+#  if !defined(ASIO_DISABLE_KQUEUE)+#   define ASIO_HAS_KQUEUE 1+#  endif // !defined(ASIO_DISABLE_KQUEUE)+# endif // !defined(ASIO_HAS_KQUEUE)+#endif // (defined(__MACH__) && defined(__APPLE__))+       //   || defined(__FreeBSD__)+       //   || defined(__NetBSD__)+       //   || defined(__OpenBSD__)++// Solaris: /dev/poll.+#if defined(__sun)+# if !defined(ASIO_HAS_DEV_POLL)+#  if !defined(ASIO_DISABLE_DEV_POLL)+#   define ASIO_HAS_DEV_POLL 1+#  endif // !defined(ASIO_DISABLE_DEV_POLL)+# endif // !defined(ASIO_HAS_DEV_POLL)+#endif // defined(__sun)++// Serial ports.+#if !defined(ASIO_HAS_SERIAL_PORT)+# if defined(ASIO_HAS_IOCP) \+  || !defined(ASIO_WINDOWS) \+  && !defined(ASIO_WINDOWS_RUNTIME) \+  && !defined(__CYGWIN__)+#  if !defined(__SYMBIAN32__)+#   if !defined(ASIO_DISABLE_SERIAL_PORT)+#    define ASIO_HAS_SERIAL_PORT 1+#   endif // !defined(ASIO_DISABLE_SERIAL_PORT)+#  endif // !defined(__SYMBIAN32__)+# endif // defined(ASIO_HAS_IOCP)+        //   || !defined(ASIO_WINDOWS)+        //   && !defined(ASIO_WINDOWS_RUNTIME)+        //   && !defined(__CYGWIN__)+#endif // !defined(ASIO_HAS_SERIAL_PORT)++// Windows: stream handles.+#if !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)+# if !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE)+#  if defined(ASIO_HAS_IOCP)+#   define ASIO_HAS_WINDOWS_STREAM_HANDLE 1+#  endif // defined(ASIO_HAS_IOCP)+# endif // !defined(ASIO_DISABLE_WINDOWS_STREAM_HANDLE)+#endif // !defined(ASIO_HAS_WINDOWS_STREAM_HANDLE)++// Windows: random access handles.+#if !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)+# if !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)+#  if defined(ASIO_HAS_IOCP)+#   define ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1+#  endif // defined(ASIO_HAS_IOCP)+# endif // !defined(ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)+#endif // !defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)++// Windows: object handles.+#if !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)+# if !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)+#  if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+#   if !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)+#    define ASIO_HAS_WINDOWS_OBJECT_HANDLE 1+#   endif // !defined(UNDER_CE) && !defined(ASIO_WINDOWS_APP)+#  endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)+# endif // !defined(ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)+#endif // !defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE)++// Windows: OVERLAPPED wrapper.+#if !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)+# if !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)+#  if defined(ASIO_HAS_IOCP)+#   define ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1+#  endif // defined(ASIO_HAS_IOCP)+# endif // !defined(ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)+#endif // !defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR)++// POSIX: stream-oriented file descriptors.+#if !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)+# if !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)+#  if !defined(ASIO_WINDOWS) \+  && !defined(ASIO_WINDOWS_RUNTIME) \+  && !defined(__CYGWIN__)+#   define ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1+#  endif // !defined(ASIO_WINDOWS)+         //   && !defined(ASIO_WINDOWS_RUNTIME)+         //   && !defined(__CYGWIN__)+# endif // !defined(ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)+#endif // !defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR)++// UNIX domain sockets.+#if !defined(ASIO_HAS_LOCAL_SOCKETS)+# if !defined(ASIO_DISABLE_LOCAL_SOCKETS)+#  if !defined(ASIO_WINDOWS_RUNTIME)+#   define ASIO_HAS_LOCAL_SOCKETS 1+#  endif // !defined(ASIO_WINDOWS_RUNTIME)+# endif // !defined(ASIO_DISABLE_LOCAL_SOCKETS)+#endif // !defined(ASIO_HAS_LOCAL_SOCKETS)++// Files.+#if !defined(ASIO_HAS_FILE)+# if !defined(ASIO_DISABLE_FILE)+#  if defined(ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)+#   define ASIO_HAS_FILE 1+#  elif defined(ASIO_HAS_IO_URING)+#   define ASIO_HAS_FILE 1+#  endif // defined(ASIO_HAS_IO_URING)+# endif // !defined(ASIO_DISABLE_FILE)+#endif // !defined(ASIO_HAS_FILE)++// Pipes.+#if !defined(ASIO_HAS_PIPE)+# if defined(ASIO_HAS_IOCP) \+  || !defined(ASIO_WINDOWS) \+  && !defined(ASIO_WINDOWS_RUNTIME) \+  && !defined(__CYGWIN__)+#  if !defined(__SYMBIAN32__)+#   if !defined(ASIO_DISABLE_PIPE)+#    define ASIO_HAS_PIPE 1+#   endif // !defined(ASIO_DISABLE_PIPE)+#  endif // !defined(__SYMBIAN32__)+# endif // defined(ASIO_HAS_IOCP)+        //   || !defined(ASIO_WINDOWS)+        //   && !defined(ASIO_WINDOWS_RUNTIME)+        //   && !defined(__CYGWIN__)+#endif // !defined(ASIO_HAS_PIPE)++// Can use sigaction() instead of signal().+#if !defined(ASIO_HAS_SIGACTION)+# if !defined(ASIO_DISABLE_SIGACTION)+#  if !defined(ASIO_WINDOWS) \+  && !defined(ASIO_WINDOWS_RUNTIME) \+  && !defined(__CYGWIN__)+#   define ASIO_HAS_SIGACTION 1+#  endif // !defined(ASIO_WINDOWS)+         //   && !defined(ASIO_WINDOWS_RUNTIME)+         //   && !defined(__CYGWIN__)+# endif // !defined(ASIO_DISABLE_SIGACTION)+#endif // !defined(ASIO_HAS_SIGACTION)++// Can use signal().+#if !defined(ASIO_HAS_SIGNAL)+# if !defined(ASIO_DISABLE_SIGNAL)+#  if !defined(UNDER_CE)+#   define ASIO_HAS_SIGNAL 1+#  endif // !defined(UNDER_CE)+# endif // !defined(ASIO_DISABLE_SIGNAL)+#endif // !defined(ASIO_HAS_SIGNAL)++// Can use getaddrinfo() and getnameinfo().+#if !defined(ASIO_HAS_GETADDRINFO)+# if !defined(ASIO_DISABLE_GETADDRINFO)+#  if defined(ASIO_WINDOWS) || defined(__CYGWIN__)+#   if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)+#    define ASIO_HAS_GETADDRINFO 1+#   elif defined(UNDER_CE)+#    define ASIO_HAS_GETADDRINFO 1+#   endif // defined(UNDER_CE)+#  elif defined(__MACH__) && defined(__APPLE__)+#   if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)+#    if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)+#     define ASIO_HAS_GETADDRINFO 1+#    endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)+#   else // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)+#    define ASIO_HAS_GETADDRINFO 1+#   endif // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)+#  else // defined(__MACH__) && defined(__APPLE__)+#   define ASIO_HAS_GETADDRINFO 1+#  endif // defined(__MACH__) && defined(__APPLE__)+# endif // !defined(ASIO_DISABLE_GETADDRINFO)+#endif // !defined(ASIO_HAS_GETADDRINFO)++// Whether standard iostreams are disabled.+#if !defined(ASIO_NO_IOSTREAM)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_IOSTREAM)+#  define ASIO_NO_IOSTREAM 1+# endif // !defined(BOOST_NO_IOSTREAM)+#endif // !defined(ASIO_NO_IOSTREAM)++// Whether exception handling is disabled.+#if !defined(ASIO_NO_EXCEPTIONS)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_EXCEPTIONS)+#  define ASIO_NO_EXCEPTIONS 1+# endif // !defined(BOOST_NO_EXCEPTIONS)+#endif // !defined(ASIO_NO_EXCEPTIONS)++// Whether the typeid operator is supported.+#if !defined(ASIO_NO_TYPEID)+# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_TYPEID)+#  define ASIO_NO_TYPEID 1+# endif // !defined(BOOST_NO_TYPEID)+#endif // !defined(ASIO_NO_TYPEID)++// Threads.+#if !defined(ASIO_HAS_THREADS)+# if !defined(ASIO_DISABLE_THREADS)+#  if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)+#   define ASIO_HAS_THREADS 1+#  elif defined(__GNUC__) && !defined(__MINGW32__) \+     && !defined(linux) && !defined(__linux) && !defined(__linux__)+#   define ASIO_HAS_THREADS 1+#  elif defined(_MT) || defined(__MT__)+#   define ASIO_HAS_THREADS 1+#  elif defined(_REENTRANT)+#   define ASIO_HAS_THREADS 1+#  elif defined(__APPLE__)+#   define ASIO_HAS_THREADS 1+#  elif defined(__HAIKU__)+#   define ASIO_HAS_THREADS 1+#  elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)+#   define ASIO_HAS_THREADS 1+#  elif defined(_PTHREADS)+#   define ASIO_HAS_THREADS 1+#  endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)+# endif // !defined(ASIO_DISABLE_THREADS)+#endif // !defined(ASIO_HAS_THREADS)++// POSIX threads.+#if !defined(ASIO_HAS_PTHREADS)+# if defined(ASIO_HAS_THREADS)+#  if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)+#   define ASIO_HAS_PTHREADS 1+#  elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)+#   define ASIO_HAS_PTHREADS 1+#  elif defined(__HAIKU__)+#   define ASIO_HAS_PTHREADS 1+#  endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)+# endif // defined(ASIO_HAS_THREADS)+#endif // !defined(ASIO_HAS_PTHREADS)++// Helper to prevent macro expansion.+#define ASIO_PREVENT_MACRO_SUBSTITUTION++// Helper to define in-class constants.+#if !defined(ASIO_STATIC_CONSTANT)+# if !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)+#  define ASIO_STATIC_CONSTANT(type, assignment) \+    BOOST_STATIC_CONSTANT(type, assignment)+# else // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)+#  define ASIO_STATIC_CONSTANT(type, assignment) \+    static const type assignment+# endif // !defined(ASIO_DISABLE_BOOST_STATIC_CONSTANT)+#endif // !defined(ASIO_STATIC_CONSTANT)++// Boost align library.+#if !defined(ASIO_HAS_BOOST_ALIGN)+# if !defined(ASIO_DISABLE_BOOST_ALIGN)+#  if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105600)+#   define ASIO_HAS_BOOST_ALIGN 1+#  endif // defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105600)+# endif // !defined(ASIO_DISABLE_BOOST_ALIGN)+#endif // !defined(ASIO_HAS_BOOST_ALIGN)++// Boost array library.+#if !defined(ASIO_HAS_BOOST_ARRAY)+# if !defined(ASIO_DISABLE_BOOST_ARRAY)+#  define ASIO_HAS_BOOST_ARRAY 1+# endif // !defined(ASIO_DISABLE_BOOST_ARRAY)+#endif // !defined(ASIO_HAS_BOOST_ARRAY)++// Boost assert macro.+#if !defined(ASIO_HAS_BOOST_ASSERT)+# if !defined(ASIO_DISABLE_BOOST_ASSERT)+#  define ASIO_HAS_BOOST_ASSERT 1+# endif // !defined(ASIO_DISABLE_BOOST_ASSERT)+#endif // !defined(ASIO_HAS_BOOST_ASSERT)++// Boost limits header.+#if !defined(ASIO_HAS_BOOST_LIMITS)+# if !defined(ASIO_DISABLE_BOOST_LIMITS)+#  define ASIO_HAS_BOOST_LIMITS 1+# endif // !defined(ASIO_DISABLE_BOOST_LIMITS)+#endif // !defined(ASIO_HAS_BOOST_LIMITS)++// Boost throw_exception function.+#if !defined(ASIO_HAS_BOOST_THROW_EXCEPTION)+# if !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION)+#  define ASIO_HAS_BOOST_THROW_EXCEPTION 1+# endif // !defined(ASIO_DISABLE_BOOST_THROW_EXCEPTION)+#endif // !defined(ASIO_HAS_BOOST_THROW_EXCEPTION)++// Boost regex library.+#if !defined(ASIO_HAS_BOOST_REGEX)+# if !defined(ASIO_DISABLE_BOOST_REGEX)+#  define ASIO_HAS_BOOST_REGEX 1+# endif // !defined(ASIO_DISABLE_BOOST_REGEX)+#endif // !defined(ASIO_HAS_BOOST_REGEX)++// Boost bind function.+#if !defined(ASIO_HAS_BOOST_BIND)+# if !defined(ASIO_DISABLE_BOOST_BIND)+#  define ASIO_HAS_BOOST_BIND 1+# endif // !defined(ASIO_DISABLE_BOOST_BIND)+#endif // !defined(ASIO_HAS_BOOST_BIND)++// Boost's BOOST_WORKAROUND macro.+#if !defined(ASIO_HAS_BOOST_WORKAROUND)+# if !defined(ASIO_DISABLE_BOOST_WORKAROUND)+#  define ASIO_HAS_BOOST_WORKAROUND 1+# endif // !defined(ASIO_DISABLE_BOOST_WORKAROUND)+#endif // !defined(ASIO_HAS_BOOST_WORKAROUND)++// Microsoft Visual C++'s secure C runtime library.+#if !defined(ASIO_HAS_SECURE_RTL)+# if !defined(ASIO_DISABLE_SECURE_RTL)+#  if defined(ASIO_MSVC) \+    && (ASIO_MSVC >= 1400) \+    && !defined(UNDER_CE)+#   define ASIO_HAS_SECURE_RTL 1+#  endif // defined(ASIO_MSVC)+         // && (ASIO_MSVC >= 1400)+         // && !defined(UNDER_CE)+# endif // !defined(ASIO_DISABLE_SECURE_RTL)+#endif // !defined(ASIO_HAS_SECURE_RTL)++// Handler hooking. Disabled for ancient Borland C++ and gcc compilers.+#if !defined(ASIO_HAS_HANDLER_HOOKS)+# if !defined(ASIO_DISABLE_HANDLER_HOOKS)+#  if defined(__GNUC__)+#   if (__GNUC__ >= 3)+#    define ASIO_HAS_HANDLER_HOOKS 1+#   endif // (__GNUC__ >= 3)+#  elif !defined(__BORLANDC__) || defined(__clang__)+#   define ASIO_HAS_HANDLER_HOOKS 1+#  endif // !defined(__BORLANDC__) || defined(__clang__)+# endif // !defined(ASIO_DISABLE_HANDLER_HOOKS)+#endif // !defined(ASIO_HAS_HANDLER_HOOKS)++// Support for the __thread keyword extension.+#if !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)+# if defined(__linux__)+#  if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+#   if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)+#    if !defined(__INTEL_COMPILER) && !defined(__ICL) \+       && !(defined(__clang__) && defined(__ANDROID__))+#     define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1+#     define ASIO_THREAD_KEYWORD __thread+#    elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)+#     define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1+#    endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)+           // && !(defined(__clang__) && defined(__ANDROID__))+#   endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)+#  endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+# endif // defined(__linux__)+# if defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME)+#  if (_MSC_VER >= 1700)+#   define ASIO_HAS_THREAD_KEYWORD_EXTENSION 1+#   define ASIO_THREAD_KEYWORD __declspec(thread)+#  endif // (_MSC_VER >= 1700)+# endif // defined(ASIO_MSVC) && defined(ASIO_WINDOWS_RUNTIME)+#endif // !defined(ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)+#if !defined(ASIO_THREAD_KEYWORD)+# define ASIO_THREAD_KEYWORD __thread+#endif // !defined(ASIO_THREAD_KEYWORD)++// Support for POSIX ssize_t typedef.+#if !defined(ASIO_DISABLE_SSIZE_T)+# if defined(__linux__) \+   || (defined(__MACH__) && defined(__APPLE__))+#  define ASIO_HAS_SSIZE_T 1+# endif // defined(__linux__)+        //   || (defined(__MACH__) && defined(__APPLE__))+#endif // !defined(ASIO_DISABLE_SSIZE_T)++// Helper macros to manage transition away from error_code return values.+#if defined(ASIO_NO_DEPRECATED)+# define ASIO_SYNC_OP_VOID void+# define ASIO_SYNC_OP_VOID_RETURN(e) return+#else // defined(ASIO_NO_DEPRECATED)+# define ASIO_SYNC_OP_VOID asio::error_code+# define ASIO_SYNC_OP_VOID_RETURN(e) return e+#endif // defined(ASIO_NO_DEPRECATED)++// Newer gcc, clang need special treatment to suppress unused typedef warnings.+#if defined(__clang__)+# if defined(__apple_build_version__)+#  if (__clang_major__ >= 7)+#   define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))+#  endif // (__clang_major__ >= 7)+# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \+    || (__clang_major__ > 3)+#  define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))+# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6))+        //   || (__clang_major__ > 3)+#elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#  define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)+#endif // defined(__GNUC__)+#if !defined(ASIO_UNUSED_TYPEDEF)+# define ASIO_UNUSED_TYPEDEF+#endif // !defined(ASIO_UNUSED_TYPEDEF)++// Some versions of gcc generate spurious warnings about unused variables.+#if defined(__GNUC__)+# if (__GNUC__ >= 4)+#  define ASIO_UNUSED_VARIABLE __attribute__((__unused__))+# endif // (__GNUC__ >= 4)+#endif // defined(__GNUC__)+#if !defined(ASIO_UNUSED_VARIABLE)+# define ASIO_UNUSED_VARIABLE+#endif // !defined(ASIO_UNUSED_VARIABLE)++// Helper macro to tell the optimiser what may be assumed to be true.+#if defined(ASIO_MSVC)+# define ASIO_ASSUME(expr) __assume(expr)+#elif defined(__clang__)+# if __has_builtin(__builtin_assume)+#  define ASIO_ASSUME(expr) __builtin_assume(expr)+# endif // __has_builtin(__builtin_assume)+#elif defined(__GNUC__)+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+#  define ASIO_ASSUME(expr) if (expr) {} else { __builtin_unreachable(); }+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)+#endif // defined(__GNUC__)+#if !defined(ASIO_ASSUME)+# define ASIO_ASSUME(expr) (void)0+#endif // !defined(ASIO_ASSUME)++// Support the co_await keyword on compilers known to allow it.+#if !defined(ASIO_HAS_CO_AWAIT)+# if !defined(ASIO_DISABLE_CO_AWAIT)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705) && !defined(__clang__)+#    define ASIO_HAS_CO_AWAIT 1+#   elif (_MSC_FULL_VER >= 190023506)+#    if defined(_RESUMABLE_FUNCTIONS_SUPPORTED)+#     define ASIO_HAS_CO_AWAIT 1+#    endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)+#   endif // (_MSC_FULL_VER >= 190023506)+#  elif defined(__clang__)+#   if (__clang_major__ >= 14)+#    if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)+#     if __has_include(<coroutine>)+#      define ASIO_HAS_CO_AWAIT 1+#     endif // __has_include(<coroutine>)+#    elif (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)+#     if __has_include(<experimental/coroutine>)+#      define ASIO_HAS_CO_AWAIT 1+#     endif // __has_include(<experimental/coroutine>)+#    endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)+#   else // (__clang_major__ >= 14)+#    if (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)+#     if __has_include(<experimental/coroutine>)+#      define ASIO_HAS_CO_AWAIT 1+#     endif // __has_include(<experimental/coroutine>)+#    endif // (__cplusplus >= 201703) && (__cpp_coroutines >= 201703)+#   endif // (__clang_major__ >= 14)+#  elif defined(__GNUC__)+#   if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)+#    if __has_include(<coroutine>)+#     define ASIO_HAS_CO_AWAIT 1+#    endif // __has_include(<coroutine>)+#   endif // (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)+#  endif // defined(__GNUC__)+# endif // !defined(ASIO_DISABLE_CO_AWAIT)+#endif // !defined(ASIO_HAS_CO_AWAIT)++// Standard library support for coroutines.+#if !defined(ASIO_HAS_STD_COROUTINE)+# if !defined(ASIO_DISABLE_STD_COROUTINE)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)+#    define ASIO_HAS_STD_COROUTINE 1+#   endif // (_MSC_VER >= 1928) && (_MSVC_LANG >= 201705)+#  elif defined(__clang__)+#   if (__clang_major__ >= 14)+#    if (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)+#     if __has_include(<coroutine>)+#      define ASIO_HAS_STD_COROUTINE 1+#     endif // __has_include(<coroutine>)+#    endif // (__cplusplus >= 202002) && (__cpp_impl_coroutine >= 201902)+#   endif // (__clang_major__ >= 14)+#  elif defined(__GNUC__)+#   if (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)+#    if __has_include(<coroutine>)+#     define ASIO_HAS_STD_COROUTINE 1+#    endif // __has_include(<coroutine>)+#   endif // (__cplusplus >= 201709) && (__cpp_impl_coroutine >= 201902)+#  endif // defined(__GNUC__)+# endif // !defined(ASIO_DISABLE_STD_COROUTINE)+#endif // !defined(ASIO_HAS_STD_COROUTINE)++// Compiler support for the the [[nodiscard]] attribute.+#if !defined(ASIO_NODISCARD)+# if defined(__has_cpp_attribute)+#  if __has_cpp_attribute(nodiscard)+#   if (__cplusplus >= 201703)+#    define ASIO_NODISCARD [[nodiscard]]+#   endif // (__cplusplus >= 201703)+#  endif // __has_cpp_attribute(nodiscard)+# endif // defined(__has_cpp_attribute)+#endif // !defined(ASIO_NODISCARD)+#if !defined(ASIO_NODISCARD)+# define ASIO_NODISCARD+#endif // !defined(ASIO_NODISCARD)++// Kernel support for MSG_NOSIGNAL.+#if !defined(ASIO_HAS_MSG_NOSIGNAL)+# if defined(__linux__)+#  define ASIO_HAS_MSG_NOSIGNAL 1+# elif defined(_POSIX_VERSION)+#  if (_POSIX_VERSION >= 200809L)+#   define ASIO_HAS_MSG_NOSIGNAL 1+#  endif // _POSIX_VERSION >= 200809L+# endif // defined(_POSIX_VERSION)+#endif // !defined(ASIO_HAS_MSG_NOSIGNAL)++// Standard library support for std::hash.+#if !defined(ASIO_HAS_STD_HASH)+# if !defined(ASIO_DISABLE_STD_HASH)+#  if defined(__clang__)+#   if defined(ASIO_HAS_CLANG_LIBCXX)+#    define ASIO_HAS_STD_HASH 1+#   elif (__cplusplus >= 201103)+#    define ASIO_HAS_STD_HASH 1+#   endif // (__cplusplus >= 201103)+#  elif defined(__GNUC__)+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#    if (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#     define ASIO_HAS_STD_HASH 1+#    endif // (__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1700)+#    define ASIO_HAS_STD_HASH 1+#   endif // (_MSC_VER >= 1700)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_HASH)+#endif // !defined(ASIO_HAS_STD_HASH)++// Standard library support for std::to_address.+#if !defined(ASIO_HAS_STD_TO_ADDRESS)+# if !defined(ASIO_DISABLE_STD_TO_ADDRESS)+#  if defined(__clang__)+#   if (__cplusplus >= 202002)+#    define ASIO_HAS_STD_TO_ADDRESS 1+#   endif // (__cplusplus >= 202002)+#  elif defined(__GNUC__)+#   if (__GNUC__ >= 8)+#    if (__cplusplus >= 202002)+#     define ASIO_HAS_STD_TO_ADDRESS 1+#    endif // (__cplusplus >= 202002)+#   endif // (__GNUC__ >= 8)+#  endif // defined(__GNUC__)+#  if defined(ASIO_MSVC)+#   if (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)+#    define ASIO_HAS_STD_TO_ADDRESS 1+#   endif // (_MSC_VER >= 1922) && (_MSVC_LANG >= 202002)+#  endif // defined(ASIO_MSVC)+# endif // !defined(ASIO_DISABLE_STD_TO_ADDRESS)+#endif // !defined(ASIO_HAS_STD_TO_ADDRESS)++// Standard library support for snprintf.+#if !defined(ASIO_HAS_SNPRINTF)+# if !defined(ASIO_DISABLE_SNPRINTF)+#  if defined(__apple_build_version__)+#    if (__clang_major__ >= 14)+#     define ASIO_HAS_SNPRINTF 1+#    endif // (__clang_major__ >= 14)+#  endif // defined(__apple_build_version__) # endif // !defined(ASIO_DISABLE_SNPRINTF) #endif // !defined(ASIO_HAS_SNPRINTF) 
link/modules/asio-standalone/asio/include/asio/detail/consuming_buffers.hpp view
@@ -2,7 +2,7 @@ // detail/consuming_buffers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -35,17 +35,21 @@ };  template <typename Elem, std::size_t N>-struct prepared_buffers_max<boost::array<Elem, N>>+struct prepared_buffers_max<boost::array<Elem, N> > {   enum { value = N }; }; +#if defined(ASIO_HAS_STD_ARRAY)+ template <typename Elem, std::size_t N>-struct prepared_buffers_max<std::array<Elem, N>>+struct prepared_buffers_max<std::array<Elem, N> > {   enum { value = N }; }; +#endif // defined(ASIO_HAS_STD_ARRAY)+ // A buffer sequence used to represent a subsequence of the buffers. template <typename Buffer, std::size_t MaxBuffers> struct prepared_buffers@@ -197,39 +201,77 @@  template <> class consuming_buffers<mutable_buffer, mutable_buffer, const mutable_buffer*>-  : public consuming_single_buffer<mutable_buffer>+  : public consuming_single_buffer<ASIO_MUTABLE_BUFFER> { public:   explicit consuming_buffers(const mutable_buffer& buffer)-    : consuming_single_buffer<mutable_buffer>(buffer)+    : consuming_single_buffer<ASIO_MUTABLE_BUFFER>(buffer)   {   } };  template <> class consuming_buffers<const_buffer, mutable_buffer, const mutable_buffer*>-  : public consuming_single_buffer<const_buffer>+  : public consuming_single_buffer<ASIO_CONST_BUFFER> { public:   explicit consuming_buffers(const mutable_buffer& buffer)-    : consuming_single_buffer<const_buffer>(buffer)+    : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)   {   } };  template <> class consuming_buffers<const_buffer, const_buffer, const const_buffer*>-  : public consuming_single_buffer<const_buffer>+  : public consuming_single_buffer<ASIO_CONST_BUFFER> { public:   explicit consuming_buffers(const const_buffer& buffer)-    : consuming_single_buffer<const_buffer>(buffer)+    : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)   {   } }; +#if !defined(ASIO_NO_DEPRECATED)+ template <> class consuming_buffers<mutable_buffer,+    mutable_buffers_1, const mutable_buffer*>+  : public consuming_single_buffer<ASIO_MUTABLE_BUFFER>+{+public:+  explicit consuming_buffers(const mutable_buffers_1& buffer)+    : consuming_single_buffer<ASIO_MUTABLE_BUFFER>(buffer)+  {+  }+};++template <>+class consuming_buffers<const_buffer, mutable_buffers_1, const mutable_buffer*>+  : public consuming_single_buffer<ASIO_CONST_BUFFER>+{+public:+  explicit consuming_buffers(const mutable_buffers_1& buffer)+    : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)+  {+  }+};++template <>+class consuming_buffers<const_buffer, const_buffers_1, const const_buffer*>+  : public consuming_single_buffer<ASIO_CONST_BUFFER>+{+public:+  explicit consuming_buffers(const const_buffers_1& buffer)+    : consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)+  {+  }+};++#endif // !defined(ASIO_NO_DEPRECATED)++template <>+class consuming_buffers<mutable_buffer,     mutable_registered_buffer, const mutable_buffer*>   : public consuming_single_buffer<mutable_registered_buffer> {@@ -314,6 +356,8 @@   std::size_t total_consumed_; }; +#if defined(ASIO_HAS_STD_ARRAY)+ template <typename Buffer, typename Elem> class consuming_buffers<Buffer, std::array<Elem, 2>,     typename std::array<Elem, 2>::const_iterator>@@ -363,6 +407,8 @@   std::array<Elem, 2> buffers_;   std::size_t total_consumed_; };++#endif // defined(ASIO_HAS_STD_ARRAY)  // Specialisation for null_buffers to ensure that the null_buffers type is // always passed through to the underlying read or write operation.
link/modules/asio-standalone/asio/include/asio/detail/cstddef.hpp view
@@ -2,7 +2,7 @@ // detail/cstddef.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,7 +20,11 @@  namespace asio { +#if defined(ASIO_HAS_NULLPTR) using std::nullptr_t;+#else // defined(ASIO_HAS_NULLPTR)+struct nullptr_t {};+#endif // defined(ASIO_HAS_NULLPTR)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/detail/cstdint.hpp view
@@ -2,7 +2,7 @@ // detail/cstdint.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,10 +16,16 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <cstdint> +#if defined(ASIO_HAS_CSTDINT)+# include <cstdint>+#else // defined(ASIO_HAS_CSTDINT)+# include <boost/cstdint.hpp>+#endif // defined(ASIO_HAS_CSTDINT)+ namespace asio { +#if defined(ASIO_HAS_CSTDINT) using std::int16_t; using std::int_least16_t; using std::uint16_t;@@ -34,6 +40,22 @@ using std::uint_least64_t; using std::uintptr_t; using std::uintmax_t;+#else // defined(ASIO_HAS_CSTDINT)+using boost::int16_t;+using boost::int_least16_t;+using boost::uint16_t;+using boost::uint_least16_t;+using boost::int32_t;+using boost::int_least32_t;+using boost::uint32_t;+using boost::uint_least32_t;+using boost::int64_t;+using boost::int_least64_t;+using boost::uint64_t;+using boost::uint_least64_t;+using boost::uintptr_t;+using boost::uintmax_t;+#endif // defined(ASIO_HAS_CSTDINT)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/detail/date_time_fwd.hpp view
@@ -2,7 +2,7 @@ // detail/date_time_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/deadline_timer_service.hpp view
@@ -2,7 +2,7 @@ // detail/deadline_timer_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,7 +19,6 @@ #include <cstddef> #include "asio/associated_cancellation_slot.hpp" #include "asio/cancellation_type.hpp"-#include "asio/config.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp" #include "asio/detail/bind_handler.hpp"@@ -29,6 +28,7 @@ #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/timer_queue.hpp"+#include "asio/detail/timer_queue_ptime.hpp" #include "asio/detail/timer_scheduler.hpp" #include "asio/detail/wait_handler.hpp" #include "asio/detail/wait_op.hpp"@@ -43,19 +43,16 @@ namespace asio { namespace detail { -template <typename TimeTraits>+template <typename Time_Traits> class deadline_timer_service-  : public execution_context_service_base<deadline_timer_service<TimeTraits>>+  : public execution_context_service_base<deadline_timer_service<Time_Traits> > { public:   // The time type.-  typedef typename TimeTraits::time_type time_type;+  typedef typename Time_Traits::time_type time_type;    // The duration type.-  typedef typename TimeTraits::duration_type duration_type;--  // The allocator type.-  typedef execution_context::allocator<void> allocator_type;+  typedef typename Time_Traits::duration_type duration_type;    // The implementation type of the timer. This type is dependent on the   // underlying implementation of the timer service.@@ -64,15 +61,13 @@   {     time_type expiry;     bool might_have_pending_waits;-    typename timer_queue<TimeTraits, allocator_type>::per_timer_data timer_data;+    typename timer_queue<Time_Traits>::per_timer_data timer_data;   };    // Constructor.   deadline_timer_service(execution_context& context)     : execution_context_service_base<-        deadline_timer_service<TimeTraits>>(context),-      timer_queue_(allocator_type(context),-          config(context).get("timer", "heap_reserve", 0U)),+        deadline_timer_service<Time_Traits> >(context),       scheduler_(asio::use_service<timer_scheduler>(context))   {     scheduler_.init_task();@@ -108,11 +103,7 @@   void move_construct(implementation_type& impl,       implementation_type& other_impl)   {-    if (other_impl.might_have_pending_waits)-    {-      scheduler_.move_timer(timer_queue_,-          impl.timer_data, other_impl.timer_data);-    }+    scheduler_.move_timer(timer_queue_, impl.timer_data, other_impl.timer_data);      impl.expiry = other_impl.expiry;     other_impl.expiry = time_type();@@ -209,7 +200,7 @@   // Get the expiry time for the timer relative to now.   duration_type expires_from_now(const implementation_type& impl) const   {-    return TimeTraits::subtract(this->expiry(impl), TimeTraits::now());+    return Time_Traits::subtract(this->expiry(impl), Time_Traits::now());   }    // Set the expiry time for the timer as an absolute time.@@ -227,7 +218,7 @@       const duration_type& expiry_time, asio::error_code& ec)   {     return expires_at(impl,-        TimeTraits::add(TimeTraits::now(), expiry_time), ec);+        Time_Traits::add(Time_Traits::now(), expiry_time), ec);   }    // Set the expiry time for the timer relative to now.@@ -235,19 +226,19 @@       const duration_type& expiry_time, asio::error_code& ec)   {     return expires_at(impl,-        TimeTraits::add(TimeTraits::now(), expiry_time), ec);+        Time_Traits::add(Time_Traits::now(), expiry_time), ec);   }    // Perform a blocking wait on the timer.   void wait(implementation_type& impl, asio::error_code& ec)   {-    time_type now = TimeTraits::now();+    time_type now = Time_Traits::now();     ec = asio::error_code();-    while (TimeTraits::less_than(now, impl.expiry) && !ec)+    while (Time_Traits::less_than(now, impl.expiry) && !ec)     {-      this->do_wait(TimeTraits::to_posix_duration(-            TimeTraits::subtract(impl.expiry, now)), ec);-      now = TimeTraits::now();+      this->do_wait(Time_Traits::to_posix_duration(+            Time_Traits::subtract(impl.expiry, now)), ec);+      now = Time_Traits::now();     }   } @@ -256,7 +247,7 @@   void async_wait(implementation_type& impl,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -306,7 +297,7 @@   {   public:     op_cancellation(deadline_timer_service* s,-        typename timer_queue<TimeTraits, allocator_type>::per_timer_data* p)+        typename timer_queue<Time_Traits>::per_timer_data* p)       : service_(s),         timer_data_(p)     {@@ -326,12 +317,11 @@    private:     deadline_timer_service* service_;-    typename timer_queue<TimeTraits, allocator_type>::per_timer_data*-      timer_data_;+    typename timer_queue<Time_Traits>::per_timer_data* timer_data_;   };    // The queue of timers.-  timer_queue<TimeTraits, allocator_type> timer_queue_;+  timer_queue<Time_Traits> timer_queue_;    // The object that schedules and executes timers. Usually a reactor.   timer_scheduler& scheduler_;
link/modules/asio-standalone/asio/include/asio/detail/dependent_type.hpp view
@@ -2,7 +2,7 @@ // detail/dependent_type.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/descriptor_ops.hpp view
@@ -2,7 +2,7 @@ // detail/descriptor_ops.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/descriptor_read_op.hpp view
@@ -2,7 +2,7 @@ // detail/descriptor_read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -97,7 +97,7 @@       Handler& handler, const IoExecutor& io_ex)     : descriptor_read_op_base<MutableBufferSequence>(success_ec,         descriptor, buffers, &descriptor_read_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -115,7 +115,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -152,7 +152,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/descriptor_write_op.hpp view
@@ -2,7 +2,7 @@ // detail/descriptor_write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -96,7 +96,7 @@       Handler& handler, const IoExecutor& io_ex)     : descriptor_write_op_base<ConstBufferSequence>(success_ec,         descriptor, buffers, &descriptor_write_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -114,7 +114,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -151,7 +151,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/dev_poll_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/dev_poll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -108,9 +108,10 @@   {     start_op(op_type, descriptor, descriptor_data,         op, is_continuation, allow_speculative,-        &dev_poll_reactor::call_post_immediate_completion, this);+        &epoll_reactor::call_post_immediate_completion, this);   } +   // Cancel all operations associated with the given descriptor. The   // handlers associated with the descriptor will be invoked with the   // operation_aborted error.@@ -140,39 +141,38 @@   ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);    // Add a new timer queue to the reactor.-  template <typename TimeTraits, typename Allocator>-  void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+  template <typename Time_Traits>+  void add_timer_queue(timer_queue<Time_Traits>& queue);    // Remove a timer queue from the reactor.-  template <typename TimeTraits, typename Allocator>-  void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+  template <typename Time_Traits>+  void remove_timer_queue(timer_queue<Time_Traits>& queue);    // Schedule a new operation in the given timer queue to expire at the   // specified absolute time.-  template <typename TimeTraits, typename Allocator>-  void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,-      const typename TimeTraits::time_type& time,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-      wait_op* op);+  template <typename Time_Traits>+  void schedule_timer(timer_queue<Time_Traits>& queue,+      const typename Time_Traits::time_type& time,+      typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);    // Cancel the timer operations associated with the given token. Returns the   // number of operations that have been posted or dispatched.-  template <typename TimeTraits, typename Allocator>-  std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+  template <typename Time_Traits>+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& timer,       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());    // Cancel the timer operations associated with the given key.-  template <typename TimeTraits, typename Allocator>-  void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+  template <typename Time_Traits>+  void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data* timer,       void* cancellation_key);    // Move the timer operations associated with the given timer.-  template <typename TimeTraits, typename Allocator>-  void move_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+  template <typename Time_Traits>+  void move_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& target,+      typename timer_queue<Time_Traits>::per_timer_data& source);    // Run /dev/poll once until interrupted or events are ready to be dispatched.   ASIO_DECL void run(long usec, op_queue<operation>& ops);
link/modules/asio-standalone/asio/include/asio/detail/epoll_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/epoll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -55,8 +55,11 @@     connect_op = 1, except_op = 2, max_ops = 3 };    // Per-descriptor queues.-  struct descriptor_state : operation+  class descriptor_state : operation   {+    friend class epoll_reactor;+    friend class object_pool_access;+     descriptor_state* next_;     descriptor_state* prev_; @@ -68,7 +71,7 @@     bool try_speculative_[max_ops];     bool shutdown_; -    ASIO_DECL descriptor_state(bool locking, int spin_count);+    ASIO_DECL descriptor_state(bool locking);     void set_ready_events(uint32_t events) { task_result_ = events; }     void add_ready_events(uint32_t events) { task_result_ |= events; }     ASIO_DECL operation* perform_io(uint32_t events);@@ -169,39 +172,38 @@       per_descriptor_data& descriptor_data);    // Add a new timer queue to the reactor.-  template <typename TimeTraits, typename Allocator>-  void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+  template <typename Time_Traits>+  void add_timer_queue(timer_queue<Time_Traits>& timer_queue);    // Remove a timer queue from the reactor.-  template <typename TimeTraits, typename Allocator>-  void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+  template <typename Time_Traits>+  void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);    // Schedule a new operation in the given timer queue to expire at the   // specified absolute time.-  template <typename TimeTraits, typename Allocator>-  void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,-      const typename TimeTraits::time_type& time,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-      wait_op* op);+  template <typename Time_Traits>+  void schedule_timer(timer_queue<Time_Traits>& queue,+      const typename Time_Traits::time_type& time,+      typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);    // Cancel the timer operations associated with the given token. Returns the   // number of operations that have been posted or dispatched.-  template <typename TimeTraits, typename Allocator>-  std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+  template <typename Time_Traits>+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& timer,       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());    // Cancel the timer operations associated with the given key.-  template <typename TimeTraits, typename Allocator>-  void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+  template <typename Time_Traits>+  void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data* timer,       void* cancellation_key);    // Move the timer operations associated with the given timer.-  template <typename TimeTraits, typename Allocator>-  void move_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+  template <typename Time_Traits>+  void move_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& target,+      typename timer_queue<Time_Traits>::per_timer_data& source);    // Run epoll once until interrupted or events are ready to be dispatched.   ASIO_DECL void run(long usec, op_queue<operation>& ops);@@ -267,18 +269,11 @@   // Whether the service has been shut down.   bool shutdown_; -  // Whether I/O locking is enabled.-  const bool io_locking_;--  // How any times to spin waiting for the I/O mutex.-  const int io_locking_spin_count_;-   // Mutex to protect access to the registered descriptors.   mutex registered_descriptors_mutex_;    // Keep track of all registered descriptors.-  object_pool<descriptor_state, execution_context::allocator<void>>-    registered_descriptors_;+  object_pool<descriptor_state> registered_descriptors_;    // Helper class to do post-perform_io cleanup.   struct perform_io_cleanup_on_block_exit;
link/modules/asio-standalone/asio/include/asio/detail/event.hpp view
@@ -2,7 +2,7 @@ // detail/event.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,8 +23,10 @@ # include "asio/detail/win_event.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_event.hpp"-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # include "asio/detail/std_event.hpp"+#else+# error Only Windows, POSIX and std::condition_variable are supported! #endif  namespace asio {@@ -36,7 +38,7 @@ typedef win_event event; #elif defined(ASIO_HAS_PTHREADS) typedef posix_event event;-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) typedef std_event event; #endif 
link/modules/asio-standalone/asio/include/asio/detail/eventfd_select_interrupter.hpp view
@@ -2,7 +2,7 @@ // detail/eventfd_select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/exception.hpp view
@@ -2,7 +2,7 @@ // detail/exception.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,13 +16,24 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <exception> +#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+# include <exception>+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+# include <boost/exception_ptr.hpp>+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+ namespace asio { +#if defined(ASIO_HAS_STD_EXCEPTION_PTR) using std::exception_ptr; using std::current_exception; using std::rethrow_exception;+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+using boost::exception_ptr;+using boost::current_exception;+using boost::rethrow_exception;+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/detail/executor_function.hpp view
@@ -2,7 +2,7 @@ // detail/executor_function.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,6 +17,7 @@  #include "asio/detail/config.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp"  #include "asio/detail/push_options.hpp"@@ -24,6 +25,8 @@ namespace asio { namespace detail { +#if defined(ASIO_HAS_MOVE)+ // Lightweight, move-only function object wrapper. class executor_function {@@ -35,11 +38,11 @@     typedef impl<F, Alloc> impl_type;     typename impl_type::ptr p = {       detail::addressof(a), impl_type::ptr::allocate(a), 0 };-    impl_ = new (p.v) impl_type(static_cast<F&&>(f), a);+    impl_ = new (p.v) impl_type(ASIO_MOVE_CAST(F)(f), a);     p.v = 0;   } -  executor_function(executor_function&& other) noexcept+  executor_function(executor_function&& other) ASIO_NOEXCEPT     : impl_(other.impl_)   {     other.impl_ = 0;@@ -76,8 +79,8 @@         thread_info_base::executor_function_tag, impl);      template <typename F>-    impl(F&& f, const Alloc& a)-      : function_(static_cast<F&&>(f)),+    impl(ASIO_MOVE_ARG(F) f, const Alloc& a)+      : function_(ASIO_MOVE_CAST(F)(f)),         allocator_(a)     {       complete_ = &executor_function::complete<Function, Alloc>;@@ -103,25 +106,74 @@     // associated with the function. Consequently, a local copy of the function     // is required to ensure that any owning sub-object remains valid until     // after we have deallocated the memory here.-    Function function(static_cast<Function&&>(i->function_));+    Function function(ASIO_MOVE_CAST(Function)(i->function_));     p.reset();      // Make the upcall if required.     if (call)     {-      static_cast<Function&&>(function)();+      asio_handler_invoke_helpers::invoke(function, function);     }   }    impl_base* impl_; }; +#else // defined(ASIO_HAS_MOVE)++// Not so lightweight, copyable function object wrapper.+class executor_function+{+public:+  template <typename F, typename Alloc>+  explicit executor_function(const F& f, const Alloc&)+    : impl_(new impl<typename decay<F>::type>(f))+  {+  }++  void operator()()+  {+    impl_->complete_(impl_.get());+  }++private:+  // Base class for polymorphic function implementations.+  struct impl_base+  {+    void (*complete_)(impl_base*);+  };++  // Polymorphic function implementation.+  template <typename F>+  struct impl : impl_base+  {+    impl(const F& f)+      : function_(f)+    {+      complete_ = &executor_function::complete<F>;+    }++    F function_;+  };++  // Helper to complete function invocation.+  template <typename F>+  static void complete(impl_base* i)+  {+    static_cast<impl<F>*>(i)->function_();+  }++  shared_ptr<impl_base> impl_;+};++#endif // defined(ASIO_HAS_MOVE)+ // Lightweight, non-owning, copyable function object wrapper. class executor_function_view { public:   template <typename F>-  explicit executor_function_view(F& f) noexcept+  explicit executor_function_view(F& f) ASIO_NOEXCEPT     : complete_(&executor_function_view::complete<F>),       function_(&f)   {
link/modules/asio-standalone/asio/include/asio/detail/executor_op.hpp view
@@ -2,7 +2,7 @@ // detail/executor_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,7 @@ #include "asio/detail/config.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/scheduler_operation.hpp"  #include "asio/detail/push_options.hpp"@@ -33,9 +34,9 @@   ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(executor_op);    template <typename H>-  executor_op(H&& h, const Alloc& allocator)+  executor_op(ASIO_MOVE_ARG(H) h, const Alloc& allocator)     : Operation(&executor_op::do_complete),-      handler_(static_cast<H&&>(h)),+      handler_(ASIO_MOVE_CAST(H)(h)),       allocator_(allocator)   {   }@@ -58,7 +59,7 @@     // with the handler. Consequently, a local copy of the handler is required     // to ensure that any owning sub-object remains valid until after we have     // deallocated the memory here.-    Handler handler(static_cast<Handler&&>(o->handler_));+    Handler handler(ASIO_MOVE_CAST(Handler)(o->handler_));     p.reset();      // Make the upcall if required.@@ -66,7 +67,7 @@     {       fenced_block b(fenced_block::half);       ASIO_HANDLER_INVOCATION_BEGIN(());-      static_cast<Handler&&>(handler)();+      asio_handler_invoke_helpers::invoke(handler, handler);       ASIO_HANDLER_INVOCATION_END;     }   }
link/modules/asio-standalone/asio/include/asio/detail/fd_set_adapter.hpp view
@@ -2,7 +2,7 @@ // detail/fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/fenced_block.hpp view
@@ -2,7 +2,7 @@ // detail/fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,8 +20,28 @@ #if !defined(ASIO_HAS_THREADS) \   || defined(ASIO_DISABLE_FENCED_BLOCK) # include "asio/detail/null_fenced_block.hpp"-#else+#elif defined(ASIO_HAS_STD_ATOMIC) # include "asio/detail/std_fenced_block.hpp"+#elif defined(__MACH__) && defined(__APPLE__)+# include "asio/detail/macos_fenced_block.hpp"+#elif defined(__sun)+# include "asio/detail/solaris_fenced_block.hpp"+#elif defined(__GNUC__) && defined(__arm__) \+  && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)+# include "asio/detail/gcc_arm_fenced_block.hpp"+#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))+# include "asio/detail/gcc_hppa_fenced_block.hpp"+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+# include "asio/detail/gcc_x86_fenced_block.hpp"+#elif defined(__GNUC__) \+  && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \+  && !defined(__INTEL_COMPILER) && !defined(__ICL) \+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)+# include "asio/detail/gcc_sync_fenced_block.hpp"+#elif defined(ASIO_WINDOWS) && !defined(UNDER_CE)+# include "asio/detail/win_fenced_block.hpp"+#else+# include "asio/detail/null_fenced_block.hpp" #endif  namespace asio {@@ -30,8 +50,28 @@ #if !defined(ASIO_HAS_THREADS) \   || defined(ASIO_DISABLE_FENCED_BLOCK) typedef null_fenced_block fenced_block;-#else+#elif defined(ASIO_HAS_STD_ATOMIC) typedef std_fenced_block fenced_block;+#elif defined(__MACH__) && defined(__APPLE__)+typedef macos_fenced_block fenced_block;+#elif defined(__sun)+typedef solaris_fenced_block fenced_block;+#elif defined(__GNUC__) && defined(__arm__) \+  && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)+typedef gcc_arm_fenced_block fenced_block;+#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))+typedef gcc_hppa_fenced_block fenced_block;+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+typedef gcc_x86_fenced_block fenced_block;+#elif defined(__GNUC__) \+  && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \+  && !defined(__INTEL_COMPILER) && !defined(__ICL) \+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)+typedef gcc_sync_fenced_block fenced_block;+#elif defined(ASIO_WINDOWS) && !defined(UNDER_CE)+typedef win_fenced_block fenced_block;+#else+typedef null_fenced_block fenced_block; #endif  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/functional.hpp view
@@ -2,7 +2,7 @@ // detail/functional.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,17 +16,28 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+ #include <functional> +#if !defined(ASIO_HAS_STD_FUNCTION)+# include <boost/function.hpp>+#endif // !defined(ASIO_HAS_STD_FUNCTION)+ namespace asio { namespace detail { +#if defined(ASIO_HAS_STD_FUNCTION) using std::function;+#else // defined(ASIO_HAS_STD_FUNCTION)+using boost::function;+#endif // defined(ASIO_HAS_STD_FUNCTION)  } // namespace detail +#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) using std::ref; using std::reference_wrapper;+#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/detail/future.hpp view
@@ -2,7 +2,7 @@ // detail/future.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,17 +16,18 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <future>-+#if defined(ASIO_HAS_STD_FUTURE)+# include <future> // Even though the future header is available, libstdc++ may not implement the // std::future class itself. However, we need to have already included the // future header to reliably test for _GLIBCXX_HAS_GTHREADS.-#if defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)-# if defined(_GLIBCXX_HAS_GTHREADS)+# if defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)+#  if defined(_GLIBCXX_HAS_GTHREADS)+#   define ASIO_HAS_STD_FUTURE_CLASS 1+#  endif // defined(_GLIBCXX_HAS_GTHREADS)+# else // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX) #  define ASIO_HAS_STD_FUTURE_CLASS 1-# endif // defined(_GLIBCXX_HAS_GTHREADS)-#else // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)-# define ASIO_HAS_STD_FUTURE_CLASS 1-#endif // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)+# endif // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)+#endif // defined(ASIO_HAS_STD_FUTURE)  #endif // ASIO_DETAIL_FUTURE_HPP
+ link/modules/asio-standalone/asio/include/asio/detail/gcc_arm_fenced_block.hpp view
@@ -0,0 +1,91 @@+//+// detail/gcc_arm_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP+#define ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__GNUC__) && defined(__arm__)++#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class gcc_arm_fenced_block+  : private noncopyable+{+public:+  enum half_t { half };+  enum full_t { full };++  // Constructor for a half fenced block.+  explicit gcc_arm_fenced_block(half_t)+  {+  }++  // Constructor for a full fenced block.+  explicit gcc_arm_fenced_block(full_t)+  {+    barrier();+  }++  // Destructor.+  ~gcc_arm_fenced_block()+  {+    barrier();+  }++private:+  static void barrier()+  {+#if defined(__ARM_ARCH_4__) \+    || defined(__ARM_ARCH_4T__) \+    || defined(__ARM_ARCH_5__) \+    || defined(__ARM_ARCH_5E__) \+    || defined(__ARM_ARCH_5T__) \+    || defined(__ARM_ARCH_5TE__) \+    || defined(__ARM_ARCH_5TEJ__) \+    || defined(__ARM_ARCH_6__) \+    || defined(__ARM_ARCH_6J__) \+    || defined(__ARM_ARCH_6K__) \+    || defined(__ARM_ARCH_6Z__) \+    || defined(__ARM_ARCH_6ZK__) \+    || defined(__ARM_ARCH_6T2__)+# if defined(__thumb__)+    // This is just a placeholder and almost certainly not sufficient.+    __asm__ __volatile__ ("" : : : "memory");+# else // defined(__thumb__)+    int a = 0, b = 0;+    __asm__ __volatile__ ("swp %0, %1, [%2]"+        : "=&r"(a) : "r"(1), "r"(&b) : "memory", "cc");+# endif // defined(__thumb__)+#else+    // ARMv7 and later.+    __asm__ __volatile__ ("dmb" : : : "memory");+#endif+  }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__GNUC__) && defined(__arm__)++#endif // ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP
+ link/modules/asio-standalone/asio/include/asio/detail/gcc_hppa_fenced_block.hpp view
@@ -0,0 +1,68 @@+//+// detail/gcc_hppa_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP+#define ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))++#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class gcc_hppa_fenced_block+  : private noncopyable+{+public:+  enum half_t { half };+  enum full_t { full };++  // Constructor for a half fenced block.+  explicit gcc_hppa_fenced_block(half_t)+  {+  }++  // Constructor for a full fenced block.+  explicit gcc_hppa_fenced_block(full_t)+  {+    barrier();+  }++  // Destructor.+  ~gcc_hppa_fenced_block()+  {+    barrier();+  }++private:+  static void barrier()+  {+    // This is just a placeholder and almost certainly not sufficient.+    __asm__ __volatile__ ("" : : : "memory");+  }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))++#endif // ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP
+ link/modules/asio-standalone/asio/include/asio/detail/gcc_sync_fenced_block.hpp view
@@ -0,0 +1,65 @@+//+// detail/gcc_sync_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP+#define ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__GNUC__) \+  && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \+  && !defined(__INTEL_COMPILER) && !defined(__ICL) \+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)++#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class gcc_sync_fenced_block+  : private noncopyable+{+public:+  enum half_or_full_t { half, full };++  // Constructor.+  explicit gcc_sync_fenced_block(half_or_full_t)+    : value_(0)+  {+    __sync_lock_test_and_set(&value_, 1);+  }++  // Destructor.+  ~gcc_sync_fenced_block()+  {+    __sync_lock_release(&value_);+  }++private:+  int value_;+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__GNUC__)+       // && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))+       // && !defined(__INTEL_COMPILER) && !defined(__ICL)+       // && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)++#endif // ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP
+ link/modules/asio-standalone/asio/include/asio/detail/gcc_x86_fenced_block.hpp view
@@ -0,0 +1,99 @@+//+// detail/gcc_x86_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP+#define ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))++#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class gcc_x86_fenced_block+  : private noncopyable+{+public:+  enum half_t { half };+  enum full_t { full };++  // Constructor for a half fenced block.+  explicit gcc_x86_fenced_block(half_t)+  {+  }++  // Constructor for a full fenced block.+  explicit gcc_x86_fenced_block(full_t)+  {+    lbarrier();+  }++  // Destructor.+  ~gcc_x86_fenced_block()+  {+    sbarrier();+  }++private:+  static int barrier()+  {+    int r = 0, m = 1;+    __asm__ __volatile__ (+        "xchg{l} %0, %1" :+        "=r"(r), "=m"(m) :+        "0"(1), "m"(m) :+        "memory", "cc");+    return r;+  }++  static void lbarrier()+  {+#if defined(__SSE2__)+# if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+    __builtin_ia32_lfence();+# else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+    __asm__ __volatile__ ("lfence" ::: "memory");+# endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+#else // defined(__SSE2__)+    barrier();+#endif // defined(__SSE2__)+  }++  static void sbarrier()+  {+#if defined(__SSE2__)+# if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+    __builtin_ia32_sfence();+# else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+    __asm__ __volatile__ ("sfence" ::: "memory");+# endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)+#else // defined(__SSE2__)+    barrier();+#endif // defined(__SSE2__)+  }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))++#endif // ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/global.hpp view
@@ -2,7 +2,7 @@ // detail/global.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,8 +23,10 @@ # include "asio/detail/win_global.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_global.hpp"-#else+#elif defined(ASIO_HAS_STD_CALL_ONCE) # include "asio/detail/std_global.hpp"+#else+# error Only Windows, POSIX and std::call_once are supported! #endif  namespace asio {@@ -39,7 +41,7 @@   return win_global<T>(); #elif defined(ASIO_HAS_PTHREADS)   return posix_global<T>();-#else+#elif defined(ASIO_HAS_STD_CALL_ONCE)   return std_global<T>(); #endif }
link/modules/asio-standalone/asio/include/asio/detail/handler_alloc_helpers.hpp view
@@ -2,7 +2,7 @@ // detail/handler_alloc_helpers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,12 +17,182 @@  #include "asio/detail/config.hpp" #include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp" #include "asio/detail/recycling_allocator.hpp"+#include "asio/detail/thread_info_base.hpp" #include "asio/associated_allocator.hpp"+#include "asio/handler_alloc_hook.hpp"  #include "asio/detail/push_options.hpp" -#define ASIO_DEFINE_TAGGED_HANDLER_PTR(purpose, op) \+// Calls to asio_handler_allocate and asio_handler_deallocate must be made from+// a namespace that does not contain any overloads of these functions. The+// asio_handler_alloc_helpers namespace is defined here for that purpose.+namespace asio_handler_alloc_helpers {++#if defined(ASIO_NO_DEPRECATED)+template <typename Handler>+inline void error_if_hooks_are_defined(Handler& h)+{+  using asio::asio_handler_allocate;+  // If you get an error here it is because some of your handlers still+  // overload asio_handler_allocate, but this hook is no longer used.+  (void)static_cast<asio::asio_handler_allocate_is_no_longer_used>(+    asio_handler_allocate(static_cast<std::size_t>(0),+      asio::detail::addressof(h)));++  using asio::asio_handler_deallocate;+  // If you get an error here it is because some of your handlers still+  // overload asio_handler_deallocate, but this hook is no longer used.+  (void)static_cast<asio::asio_handler_deallocate_is_no_longer_used>(+    asio_handler_deallocate(static_cast<void*>(0),+      static_cast<std::size_t>(0), asio::detail::addressof(h)));+}+#endif // defined(ASIO_NO_DEPRECATED)++template <typename Handler>+inline void* allocate(std::size_t s, Handler& h,+    std::size_t align = ASIO_DEFAULT_ALIGN)+{+#if !defined(ASIO_HAS_HANDLER_HOOKS)+  return asio::aligned_new(align, s);+#elif defined(ASIO_NO_DEPRECATED)+  // The asio_handler_allocate hook is no longer used to obtain memory.+  (void)&error_if_hooks_are_defined<Handler>;+  (void)h;+# if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+  return asio::detail::thread_info_base::allocate(+      asio::detail::thread_context::top_of_thread_call_stack(),+      s, align);+# else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+  return asio::aligned_new(align, s);+# endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+#else+  (void)align;+  using asio::asio_handler_allocate;+  return asio_handler_allocate(s, asio::detail::addressof(h));+#endif+}++template <typename Handler>+inline void deallocate(void* p, std::size_t s, Handler& h)+{+#if !defined(ASIO_HAS_HANDLER_HOOKS)+  asio::aligned_delete(p);+#elif defined(ASIO_NO_DEPRECATED)+  // The asio_handler_allocate hook is no longer used to obtain memory.+  (void)&error_if_hooks_are_defined<Handler>;+  (void)h;+#if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+  asio::detail::thread_info_base::deallocate(+      asio::detail::thread_context::top_of_thread_call_stack(), p, s);+#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+  (void)s;+  asio::aligned_delete(p);+#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+#else+  using asio::asio_handler_deallocate;+  asio_handler_deallocate(p, s, asio::detail::addressof(h));+#endif+}++} // namespace asio_handler_alloc_helpers++namespace asio {+namespace detail {++template <typename Handler, typename T>+class hook_allocator+{+public:+  typedef T value_type;++  template <typename U>+  struct rebind+  {+    typedef hook_allocator<Handler, U> other;+  };++  explicit hook_allocator(Handler& h)+    : handler_(h)+  {+  }++  template <typename U>+  hook_allocator(const hook_allocator<Handler, U>& a)+    : handler_(a.handler_)+  {+  }++  T* allocate(std::size_t n)+  {+    return static_cast<T*>(+        asio_handler_alloc_helpers::allocate(+          sizeof(T) * n, handler_, ASIO_ALIGNOF(T)));+  }++  void deallocate(T* p, std::size_t n)+  {+    asio_handler_alloc_helpers::deallocate(p, sizeof(T) * n, handler_);+  }++//private:+  Handler& handler_;+};++template <typename Handler>+class hook_allocator<Handler, void>+{+public:+  typedef void value_type;++  template <typename U>+  struct rebind+  {+    typedef hook_allocator<Handler, U> other;+  };++  explicit hook_allocator(Handler& h)+    : handler_(h)+  {+  }++  template <typename U>+  hook_allocator(const hook_allocator<Handler, U>& a)+    : handler_(a.handler_)+  {+  }++//private:+  Handler& handler_;+};++template <typename Handler, typename Allocator>+struct get_hook_allocator+{+  typedef Allocator type;++  static type get(Handler&, const Allocator& a)+  {+    return a;+  }+};++template <typename Handler, typename T>+struct get_hook_allocator<Handler, std::allocator<T> >+{+  typedef hook_allocator<Handler, T> type;++  static type get(Handler& handler, const std::allocator<T>&)+  {+    return type(handler);+  }+};++} // namespace detail+} // namespace asio++#define ASIO_DEFINE_HANDLER_PTR(op) \   struct ptr \   { \     Handler* h; \@@ -36,12 +206,12 @@     { \       typedef typename ::asio::associated_allocator< \         Handler>::type associated_allocator_type; \-      typedef typename ::asio::detail::get_recycling_allocator< \-        associated_allocator_type, purpose>::type default_allocator_type; \-      ASIO_REBIND_ALLOC(default_allocator_type, op) a( \-            ::asio::detail::get_recycling_allocator< \-              associated_allocator_type, purpose>::get( \-                ::asio::get_associated_allocator(handler))); \+      typedef typename ::asio::detail::get_hook_allocator< \+        Handler, associated_allocator_type>::type hook_allocator_type; \+      ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \+            ::asio::detail::get_hook_allocator< \+              Handler, associated_allocator_type>::get( \+                handler, ::asio::get_associated_allocator(handler))); \       return a.allocate(1); \     } \     void reset() \@@ -55,22 +225,17 @@       { \         typedef typename ::asio::associated_allocator< \           Handler>::type associated_allocator_type; \-        typedef typename ::asio::detail::get_recycling_allocator< \-          associated_allocator_type, purpose>::type default_allocator_type; \-        ASIO_REBIND_ALLOC(default_allocator_type, op) a( \-              ::asio::detail::get_recycling_allocator< \-                associated_allocator_type, purpose>::get( \-                  ::asio::get_associated_allocator(*h))); \+        typedef typename ::asio::detail::get_hook_allocator< \+          Handler, associated_allocator_type>::type hook_allocator_type; \+        ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \+              ::asio::detail::get_hook_allocator< \+                Handler, associated_allocator_type>::get( \+                  *h, ::asio::get_associated_allocator(*h))); \         a.deallocate(static_cast<op*>(v), 1); \         v = 0; \       } \     } \   } \-  /**/--#define ASIO_DEFINE_HANDLER_PTR(op) \-  ASIO_DEFINE_TAGGED_HANDLER_PTR( \-      ::asio::detail::thread_info_base::default_tag, op ) \   /**/  #define ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(purpose, op) \
link/modules/asio-standalone/asio/include/asio/detail/handler_cont_helpers.hpp view
@@ -2,7 +2,7 @@ // detail/handler_cont_helpers.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
+ link/modules/asio-standalone/asio/include/asio/detail/handler_invoke_helpers.hpp view
@@ -0,0 +1,80 @@+//+// detail/handler_invoke_helpers.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP+#define ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/memory.hpp"+#include "asio/handler_invoke_hook.hpp"++#include "asio/detail/push_options.hpp"++// Calls to asio_handler_invoke must be made from a namespace that does not+// contain overloads of this function. The asio_handler_invoke_helpers+// namespace is defined here for that purpose.+namespace asio_handler_invoke_helpers {++#if defined(ASIO_NO_DEPRECATED)+template <typename Function, typename Context>+inline void error_if_hook_is_defined(Function& function, Context& context)+{+  using asio::asio_handler_invoke;+  // If you get an error here it is because some of your handlers still+  // overload asio_handler_invoke, but this hook is no longer used.+  (void)static_cast<asio::asio_handler_invoke_is_no_longer_used>(+    asio_handler_invoke(function, asio::detail::addressof(context)));+}+#endif // defined(ASIO_NO_DEPRECATED)++template <typename Function, typename Context>+inline void invoke(Function& function, Context& context)+{+#if !defined(ASIO_HAS_HANDLER_HOOKS)+  Function tmp(function);+  tmp();+#elif defined(ASIO_NO_DEPRECATED)+  // The asio_handler_invoke hook is no longer used to invoke the function.+  (void)&error_if_hook_is_defined<Function, Context>;+  (void)context;+  function();+#else+  using asio::asio_handler_invoke;+  asio_handler_invoke(function, asio::detail::addressof(context));+#endif+}++template <typename Function, typename Context>+inline void invoke(const Function& function, Context& context)+{+#if !defined(ASIO_HAS_HANDLER_HOOKS)+  Function tmp(function);+  tmp();+#elif defined(ASIO_NO_DEPRECATED)+  // The asio_handler_invoke hook is no longer used to invoke the function.+  (void)&error_if_hook_is_defined<const Function, Context>;+  (void)context;+  Function tmp(function);+  tmp();+#else+  using asio::asio_handler_invoke;+  asio_handler_invoke(function, asio::detail::addressof(context));+#endif+}++} // namespace asio_handler_invoke_helpers++#include "asio/detail/pop_options.hpp"++#endif // ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP
link/modules/asio-standalone/asio/include/asio/detail/handler_tracking.hpp view
@@ -2,7 +2,7 @@ // detail/handler_tracking.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -99,8 +99,8 @@    private:     // Disallow copying and assignment.-    location(const location&) = delete;-    location& operator=(const location&) = delete;+    location(const location&) ASIO_DELETED;+    location& operator=(const location&) ASIO_DELETED;      friend class handler_tracking;     const char* file_;
link/modules/asio-standalone/asio/include/asio/detail/handler_type_requirements.hpp view
@@ -2,7 +2,7 @@ // detail/handler_type_requirements.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -64,7 +64,7 @@ auto zero_arg_copyable_handler_test(Handler h, void*)   -> decltype(     sizeof(Handler(static_cast<const Handler&>(h))),-    (static_cast<Handler&&>(h)()),+    (ASIO_MOVE_OR_LVALUE(Handler)(h)()),     char(0));  template <typename Handler>@@ -73,8 +73,8 @@ template <typename Handler, typename Arg1> auto one_arg_handler_test(Handler h, Arg1* a1)   -> decltype(-    sizeof(Handler(static_cast<Handler&&>(h))),-    (static_cast<Handler&&>(h)(*a1)),+    sizeof(Handler(ASIO_MOVE_CAST(Handler)(h))),+    (ASIO_MOVE_OR_LVALUE(Handler)(h)(*a1)),     char(0));  template <typename Handler>@@ -83,8 +83,8 @@ template <typename Handler, typename Arg1, typename Arg2> auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2)   -> decltype(-    sizeof(Handler(static_cast<Handler&&>(h))),-    (static_cast<Handler&&>(h)(*a1, *a2)),+    sizeof(Handler(ASIO_MOVE_CAST(Handler)(h))),+    (ASIO_MOVE_OR_LVALUE(Handler)(h)(*a1, *a2)),     char(0));  template <typename Handler>@@ -93,9 +93,9 @@ template <typename Handler, typename Arg1, typename Arg2> auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2)   -> decltype(-    sizeof(Handler(static_cast<Handler&&>(h))),-    (static_cast<Handler&&>(h)(-      *a1, static_cast<Arg2&&>(*a2))),+    sizeof(Handler(ASIO_MOVE_CAST(Handler)(h))),+    (ASIO_MOVE_OR_LVALUE(Handler)(h)(+      *a1, ASIO_MOVE_CAST(Arg2)(*a2))),     char(0));  template <typename Handler>@@ -114,15 +114,43 @@ template <typename T> T& lvref(T); template <typename T> const T& clvref(); template <typename T> const T& clvref(T);+#if defined(ASIO_HAS_MOVE) template <typename T> T rvref(); template <typename T> T rvref(T); template <typename T> T rorlvref();+#else // defined(ASIO_HAS_MOVE)+template <typename T> const T& rvref();+template <typename T> const T& rvref(T);+template <typename T> T& rorlvref();+#endif // defined(ASIO_HAS_MOVE) template <typename T> char argbyv(T);  template <int> struct handler_type_requirements { };++#define ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \+    handler_type, handler) \+  \+  typedef ASIO_HANDLER_TYPE(handler_type, \+      void()) asio_true_handler_type; \+  \+  ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \+      sizeof(asio::detail::zero_arg_copyable_handler_test( \+          asio::detail::clvref< \+            asio_true_handler_type>(), 0)) == 1, \+      "CompletionHandler type requirements not met") \+  \+  typedef asio::detail::handler_type_requirements< \+      sizeof( \+        asio::detail::argbyv( \+          asio::detail::clvref< \+            asio_true_handler_type>())) + \+      sizeof( \+        asio::detail::rorlvref< \+          asio_true_handler_type>()(), \+        char(0))> ASIO_UNUSED_TYPEDEF  #define ASIO_READ_HANDLER_CHECK( \     handler_type, handler) \
link/modules/asio-standalone/asio/include/asio/detail/handler_work.hpp view
@@ -2,7 +2,7 @@ // detail/handler_work.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,11 +19,13 @@ #include "asio/associated_allocator.hpp" #include "asio/associated_executor.hpp" #include "asio/associated_immediate_executor.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/initiate_dispatch.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/work_dispatcher.hpp" #include "asio/execution/allocator.hpp" #include "asio/execution/blocking.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/executor_work_guard.hpp"@@ -45,8 +47,17 @@  namespace execution { +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename...> class any_executor; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename, typename, typename, typename, typename,+    typename, typename, typename, typename> class any_executor;++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ } // namespace execution namespace detail { @@ -56,29 +67,31 @@ class handler_work_base { public:-  explicit handler_work_base(int, int, const Executor& ex) noexcept+  explicit handler_work_base(int, int, const Executor& ex) ASIO_NOEXCEPT     : executor_(asio::prefer(ex, execution::outstanding_work.tracked))   {   }    template <typename OtherExecutor>   handler_work_base(bool /*base1_owns_work*/, const Executor& ex,-      const OtherExecutor& /*candidate*/) noexcept+      const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT     : executor_(asio::prefer(ex, execution::outstanding_work.tracked))   {   } -  handler_work_base(const handler_work_base& other) noexcept+  handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT     : executor_(other.executor_)   {   } -  handler_work_base(handler_work_base&& other) noexcept-    : executor_(static_cast<executor_type&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+  handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(executor_type)(other.executor_))   {   }+#endif // defined(ASIO_HAS_MOVE) -  bool owns_work() const noexcept+  bool owns_work() const ASIO_NOEXCEPT   {     return true;   }@@ -86,15 +99,24 @@   template <typename Function, typename Handler>   void dispatch(Function& function, Handler& handler)   {+#if defined(ASIO_NO_DEPRECATED)     asio::prefer(executor_,         execution::allocator((get_associated_allocator)(handler))-      ).execute(static_cast<Function&&>(function));+      ).execute(ASIO_MOVE_CAST(Function)(function));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(executor_,+          execution::allocator((get_associated_allocator)(handler))),+        ASIO_MOVE_CAST(Function)(function));+#endif // defined(ASIO_NO_DEPRECATED)   }  private:-  typedef decay_t<-      prefer_result_t<Executor, execution::outstanding_work_t::tracked_t>-    > executor_type;+  typedef typename decay<+      typename prefer_result<Executor,+        execution::outstanding_work_t::tracked_t+      >::type+    >::type executor_type;    executor_type executor_; };@@ -103,15 +125,14 @@     typename IoContext, typename PolymorphicExecutor> class handler_work_base<Executor, CandidateExecutor,     IoContext, PolymorphicExecutor,-    enable_if_t<+    typename enable_if<       !execution::is_executor<Executor>::value         && (!is_same<Executor, PolymorphicExecutor>::value           || !is_same<CandidateExecutor, void>::value)-    >-  >+    >::type> { public:-  explicit handler_work_base(int, int, const Executor& ex) noexcept+  explicit handler_work_base(int, int, const Executor& ex) ASIO_NOEXCEPT     : executor_(ex),       owns_work_(true)   {@@ -119,7 +140,7 @@   }    handler_work_base(bool /*base1_owns_work*/, const Executor& ex,-      const Executor& candidate) noexcept+      const Executor& candidate) ASIO_NOEXCEPT     : executor_(ex),       owns_work_(ex != candidate)   {@@ -129,14 +150,14 @@    template <typename OtherExecutor>   handler_work_base(bool /*base1_owns_work*/, const Executor& ex,-      const OtherExecutor& /*candidate*/) noexcept+      const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT     : executor_(ex),       owns_work_(true)   {     executor_.on_work_started();   } -  handler_work_base(const handler_work_base& other) noexcept+  handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT     : executor_(other.executor_),       owns_work_(other.owns_work_)   {@@ -144,12 +165,14 @@       executor_.on_work_started();   } -  handler_work_base(handler_work_base&& other) noexcept-    : executor_(static_cast<Executor&&>(other.executor_)),+#if defined(ASIO_HAS_MOVE)+  handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)),       owns_work_(other.owns_work_)   {     other.owns_work_ = false;   }+#endif // defined(ASIO_HAS_MOVE)    ~handler_work_base()   {@@ -157,7 +180,7 @@       executor_.on_work_finished();   } -  bool owns_work() const noexcept+  bool owns_work() const ASIO_NOEXCEPT   {     return owns_work_;   }@@ -165,7 +188,7 @@   template <typename Function, typename Handler>   void dispatch(Function& function, Handler& handler)   {-    executor_.dispatch(static_cast<Function&&>(function),+    executor_.dispatch(ASIO_MOVE_CAST(Function)(function),         asio::get_associated_allocator(handler));   } @@ -176,31 +199,30 @@  template <typename Executor, typename IoContext, typename PolymorphicExecutor> class handler_work_base<Executor, void, IoContext, PolymorphicExecutor,-    enable_if_t<+    typename enable_if<       is_same<         Executor,         typename IoContext::executor_type       >::value-    >-  >+    >::type> { public:   explicit handler_work_base(int, int, const Executor&)   {   } -  bool owns_work() const noexcept+  bool owns_work() const ASIO_NOEXCEPT   {     return false;   }    template <typename Function, typename Handler>-  void dispatch(Function& function, Handler&)+  void dispatch(Function& function, Handler& handler)   {     // When using a native implementation, I/O completion handlers are     // already dispatched according to the execution context's executor's     // rules. We can call the function directly.-    static_cast<Function&&>(function)();+    asio_handler_invoke_helpers::invoke(function, handler);   } }; @@ -208,7 +230,7 @@ class handler_work_base<Executor, void, IoContext, Executor> { public:-  explicit handler_work_base(int, int, const Executor& ex) noexcept+  explicit handler_work_base(int, int, const Executor& ex) ASIO_NOEXCEPT #if !defined(ASIO_NO_TYPEID)     : executor_(         ex.target_type() == typeid(typename IoContext::executor_type)@@ -222,7 +244,7 @@   }    handler_work_base(bool /*base1_owns_work*/, const Executor& ex,-      const Executor& candidate) noexcept+      const Executor& candidate) ASIO_NOEXCEPT     : executor_(ex != candidate ? ex : Executor())   {     if (executor_)@@ -231,23 +253,25 @@    template <typename OtherExecutor>   handler_work_base(const Executor& ex,-      const OtherExecutor&) noexcept+      const OtherExecutor&) ASIO_NOEXCEPT     : executor_(ex)   {     executor_.on_work_started();   } -  handler_work_base(const handler_work_base& other) noexcept+  handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT     : executor_(other.executor_)   {     if (executor_)       executor_.on_work_started();   } -  handler_work_base(handler_work_base&& other) noexcept-    : executor_(static_cast<Executor&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+  handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(Executor)(other.executor_))   {   }+#endif // defined(ASIO_HAS_MOVE)    ~handler_work_base()   {@@ -255,7 +279,7 @@       executor_.on_work_finished();   } -  bool owns_work() const noexcept+  bool owns_work() const ASIO_NOEXCEPT   {     return !!executor_;   }@@ -263,7 +287,7 @@   template <typename Function, typename Handler>   void dispatch(Function& function, Handler& handler)   {-    executor_.dispatch(static_cast<Function&&>(function),+    executor_.dispatch(ASIO_MOVE_CAST(Function)(function),         asio::get_associated_allocator(handler));   } @@ -271,15 +295,34 @@   Executor executor_; }; -template <typename... SupportableProperties, typename CandidateExecutor,-    typename IoContext, typename PolymorphicExecutor>-class handler_work_base<execution::any_executor<SupportableProperties...>,+template <+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+    typename... SupportableProperties,+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+    typename T1, typename T2, typename T3, typename T4, typename T5,+    typename T6, typename T7, typename T8, typename T9,+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+    typename CandidateExecutor, typename IoContext,+    typename PolymorphicExecutor>+class handler_work_base<+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+    execution::any_executor<SupportableProperties...>,+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+    execution::any_executor<T1, T2, T3, T4, T5, T6, T7, T8, T9>,+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)     CandidateExecutor, IoContext, PolymorphicExecutor> { public:-  typedef execution::any_executor<SupportableProperties...> executor_type;+  typedef+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+    execution::any_executor<SupportableProperties...>+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+    execution::any_executor<T1, T2, T3, T4, T5, T6, T7, T8, T9>+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+    executor_type; -  explicit handler_work_base(int, int, const executor_type& ex) noexcept+  explicit handler_work_base(int, int,+      const executor_type& ex) ASIO_NOEXCEPT #if !defined(ASIO_NO_TYPEID)     : executor_(         ex.target_type() == typeid(typename IoContext::executor_type)@@ -292,7 +335,7 @@   }    handler_work_base(bool base1_owns_work, const executor_type& ex,-      const executor_type& candidate) noexcept+      const executor_type& candidate) ASIO_NOEXCEPT     : executor_(         !base1_owns_work && ex == candidate           ? executor_type()@@ -302,22 +345,24 @@    template <typename OtherExecutor>   handler_work_base(bool /*base1_owns_work*/, const executor_type& ex,-      const OtherExecutor& /*candidate*/) noexcept+      const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT     : executor_(asio::prefer(ex, execution::outstanding_work.tracked))   {   } -  handler_work_base(const handler_work_base& other) noexcept+  handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT     : executor_(other.executor_)   {   } -  handler_work_base(handler_work_base&& other) noexcept-    : executor_(static_cast<executor_type&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+  handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(executor_type)(other.executor_))   {   }+#endif // defined(ASIO_HAS_MOVE) -  bool owns_work() const noexcept+  bool owns_work() const ASIO_NOEXCEPT   {     return !!executor_;   }@@ -325,7 +370,11 @@   template <typename Function, typename Handler>   void dispatch(Function& function, Handler&)   {-    executor_.execute(static_cast<Function&&>(function));+#if defined(ASIO_NO_DEPRECATED)+    executor_.execute(ASIO_MOVE_CAST(Function)(function));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(executor_, ASIO_MOVE_CAST(Function)(function));+#endif // defined(ASIO_NO_DEPRECATED)   }  private:@@ -339,17 +388,16 @@ class handler_work_base<     Executor, CandidateExecutor,     IoContext, PolymorphicExecutor,-    enable_if_t<+    typename enable_if<       is_same<Executor, any_completion_executor>::value         || is_same<Executor, any_io_executor>::value-    >-  >+    >::type> { public:   typedef Executor executor_type;    explicit handler_work_base(int, int,-      const executor_type& ex) noexcept+      const executor_type& ex) ASIO_NOEXCEPT #if !defined(ASIO_NO_TYPEID)     : executor_(         ex.target_type() == typeid(typename IoContext::executor_type)@@ -362,7 +410,7 @@   }    handler_work_base(bool base1_owns_work, const executor_type& ex,-      const executor_type& candidate) noexcept+      const executor_type& candidate) ASIO_NOEXCEPT     : executor_(         !base1_owns_work && ex == candidate           ? executor_type()@@ -372,22 +420,24 @@    template <typename OtherExecutor>   handler_work_base(bool /*base1_owns_work*/, const executor_type& ex,-      const OtherExecutor& /*candidate*/) noexcept+      const OtherExecutor& /*candidate*/) ASIO_NOEXCEPT     : executor_(asio::prefer(ex, execution::outstanding_work.tracked))   {   } -  handler_work_base(const handler_work_base& other) noexcept+  handler_work_base(const handler_work_base& other) ASIO_NOEXCEPT     : executor_(other.executor_)   {   } -  handler_work_base(handler_work_base&& other) noexcept-    : executor_(static_cast<executor_type&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+  handler_work_base(handler_work_base&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(executor_type)(other.executor_))   {   }+#endif // defined(ASIO_HAS_MOVE) -  bool owns_work() const noexcept+  bool owns_work() const ASIO_NOEXCEPT   {     return !!executor_;   }@@ -395,7 +445,11 @@   template <typename Function, typename Handler>   void dispatch(Function& function, Handler&)   {-    executor_.execute(static_cast<Function&&>(function));+#if defined(ASIO_NO_DEPRECATED)+    executor_.execute(ASIO_MOVE_CAST(Function)(function));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(executor_, ASIO_MOVE_CAST(Function)(function));+#endif // defined(ASIO_NO_DEPRECATED)   }  private:@@ -407,14 +461,15 @@ template <typename Handler, typename IoExecutor, typename = void> class handler_work :   handler_work_base<IoExecutor>,-  handler_work_base<associated_executor_t<Handler, IoExecutor>, IoExecutor>+  handler_work_base<typename associated_executor<+      Handler, IoExecutor>::type, IoExecutor> { public:   typedef handler_work_base<IoExecutor> base1_type;-  typedef handler_work_base<associated_executor_t<Handler, IoExecutor>,-      IoExecutor> base2_type;+  typedef handler_work_base<typename associated_executor<+    Handler, IoExecutor>::type, IoExecutor> base2_type; -  handler_work(Handler& handler, const IoExecutor& io_ex) noexcept+  handler_work(Handler& handler, const IoExecutor& io_ex) ASIO_NOEXCEPT     : base1_type(0, 0, io_ex),       base2_type(base1_type::owns_work(),           asio::get_associated_executor(handler, io_ex), io_ex)@@ -429,7 +484,7 @@       // When using a native implementation, I/O completion handlers are       // already dispatched according to the execution context's executor's       // rules. We can call the function directly.-      static_cast<Function&&>(function)();+      asio_handler_invoke_helpers::invoke(function, handler);     }     else     {@@ -441,19 +496,18 @@ template <typename Handler, typename IoExecutor> class handler_work<     Handler, IoExecutor,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_executor<Handler,           IoExecutor>::asio_associated_executor_is_unspecialised,         void       >::value-    >-  > : handler_work_base<IoExecutor>+    >::type> : handler_work_base<IoExecutor> { public:   typedef handler_work_base<IoExecutor> base1_type; -  handler_work(Handler&, const IoExecutor& io_ex) noexcept+  handler_work(Handler&, const IoExecutor& io_ex) ASIO_NOEXCEPT     : base1_type(0, 0, io_ex)   {   }@@ -466,7 +520,7 @@       // When using a native implementation, I/O completion handlers are       // already dispatched according to the execution context's executor's       // rules. We can call the function directly.-      static_cast<Function&&>(function)();+      asio_handler_invoke_helpers::invoke(function, handler);     }     else     {@@ -481,22 +535,22 @@ public:   typedef handler_work<Handler, IoExecutor> handler_work_type; -  explicit immediate_handler_work(handler_work_type&& w)-    : handler_work_(static_cast<handler_work_type&&>(w))+  explicit immediate_handler_work(ASIO_MOVE_ARG(handler_work_type) w)+    : handler_work_(ASIO_MOVE_CAST(handler_work_type)(w))   {   }    template <typename Function>   void complete(Function& function, Handler& handler, const void* io_ex)   {-    typedef associated_immediate_executor_t<Handler, IoExecutor>+    typedef typename associated_immediate_executor<Handler, IoExecutor>::type       immediate_ex_type;      immediate_ex_type immediate_ex = (get_associated_immediate_executor)(         handler, *static_cast<const IoExecutor*>(io_ex));      (initiate_dispatch_with_executor<immediate_ex_type>(immediate_ex))(-        static_cast<Function&&>(function));+        ASIO_MOVE_CAST(Function)(function));   }  private:
link/modules/asio-standalone/asio/include/asio/detail/hash_map.hpp view
@@ -2,7 +2,7 @@ // detail/hash_map.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp view
@@ -2,7 +2,7 @@ // detail/impl/buffer_sequence_adapter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/descriptor_ops.ipp view
@@ -2,7 +2,7 @@ // detail/impl/descriptor_ops.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -69,24 +69,18 @@         ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK); #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)       ioctl_arg_type arg = 0;-      if ((state & possible_dup) == 0)-      {-        result = ::ioctl(d, FIONBIO, &arg);-        get_last_error(ec, result < 0);-      }-      if ((state & possible_dup) != 0 # if defined(ENOTTY)-          || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)-          || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)-        )+      result = ::ioctl(d, FIONBIO, &arg);+      get_last_error(ec, result < 0);+      if (ec.value() == ENOTTY)       {         int flags = ::fcntl(d, F_GETFL, 0);         if (flags >= 0)           ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK);       }+# else // defined(ENOTTY)+      ::ioctl(d, FIONBIO, &arg);+# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)       state &= ~non_blocking; @@ -113,35 +107,26 @@   if (result >= 0)   {     int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));-    result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0;+    result = ::fcntl(d, F_SETFL, flag);     get_last_error(ec, result < 0);   } #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)   ioctl_arg_type arg = (value ? 1 : 0);-  int result = 0;-  if ((state & possible_dup) == 0)-  {-    result = ::ioctl(d, FIONBIO, &arg);-    get_last_error(ec, result < 0);-  }-  if ((state & possible_dup) != 0+  int result = ::ioctl(d, FIONBIO, &arg);+  get_last_error(ec, result < 0); # if defined(ENOTTY)-      || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)-      || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)-    )+  if (ec.value() == ENOTTY)   {     result = ::fcntl(d, F_GETFL, 0);     get_last_error(ec, result < 0);     if (result >= 0)     {       int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));-      result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0;+      result = ::fcntl(d, F_SETFL, flag);       get_last_error(ec, result < 0);     }   }+# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)    if (result >= 0)@@ -185,35 +170,26 @@   if (result >= 0)   {     int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));-    result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0;+    result = ::fcntl(d, F_SETFL, flag);     get_last_error(ec, result < 0);   } #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)   ioctl_arg_type arg = (value ? 1 : 0);-  int result = 0;-  if ((state & possible_dup) == 0)-  {-    result = ::ioctl(d, FIONBIO, &arg);-    get_last_error(ec, result < 0);-  }-  if ((state & possible_dup) != 0+  int result = ::ioctl(d, FIONBIO, &arg);+  get_last_error(ec, result < 0); # if defined(ENOTTY)-      || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)-      || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)-    )+  if (ec.value() == ENOTTY)   {     result = ::fcntl(d, F_GETFL, 0);     get_last_error(ec, result < 0);     if (result >= 0)     {       int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));-      result = (flag != result) ? ::fcntl(d, F_SETFL, flag) : 0;+      result = ::fcntl(d, F_SETFL, flag);       get_last_error(ec, result < 0);     }   }+# endif // defined(ENOTTY) #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)    if (result >= 0)
link/modules/asio-standalone/asio/include/asio/detail/impl/dev_poll_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/impl/dev_poll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -32,26 +32,22 @@   scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::add_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void dev_poll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) {   do_add_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::remove_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void dev_poll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) {   do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::schedule_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    const typename TimeTraits::time_type& time,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-    wait_op* op)+template <typename Time_Traits>+void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,+    const typename Time_Traits::time_type& time,+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) {   asio::detail::mutex::scoped_lock lock(mutex_); @@ -67,10 +63,9 @@     interrupter_.interrupt(); } -template <typename TimeTraits, typename Allocator>-std::size_t dev_poll_reactor::cancel_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t dev_poll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& timer,     std::size_t max_cancelled) {   asio::detail::mutex::scoped_lock lock(mutex_);@@ -81,10 +76,9 @@   return n; } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::cancel_timer_by_key(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void dev_poll_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data* timer,     void* cancellation_key) {   asio::detail::mutex::scoped_lock lock(mutex_);@@ -94,10 +88,10 @@   scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void dev_poll_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void dev_poll_reactor::move_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& target,+    typename timer_queue<Time_Traits>::per_timer_data& source) {   asio::detail::mutex::scoped_lock lock(mutex_);   op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/dev_poll_reactor.ipp view
@@ -2,7 +2,7 @@ // detail/impl/dev_poll_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -66,7 +66,7 @@   timer_queues_.get_all_timers(ops);    scheduler_.abandon_operations(ops);-}+}   void dev_poll_reactor::notify_fork(     asio::execution_context::fork_event fork_ev)
link/modules/asio-standalone/asio/include/asio/detail/impl/epoll_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/impl/epoll_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -30,25 +30,22 @@   scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::add_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void epoll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) {   do_add_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::remove_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void epoll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) {   do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::schedule_timer(timer_queue<TimeTraits, Allocator>& queue,-    const typename TimeTraits::time_type& time,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-    wait_op* op)+template <typename Time_Traits>+void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,+    const typename Time_Traits::time_type& time,+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) {   mutex::scoped_lock lock(mutex_); @@ -64,10 +61,9 @@     update_timeout(); } -template <typename TimeTraits, typename Allocator>-std::size_t epoll_reactor::cancel_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t epoll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& timer,     std::size_t max_cancelled) {   mutex::scoped_lock lock(mutex_);@@ -78,10 +74,9 @@   return n; } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::cancel_timer_by_key(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void epoll_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data* timer,     void* cancellation_key) {   mutex::scoped_lock lock(mutex_);@@ -91,10 +86,10 @@   scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void epoll_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void epoll_reactor::move_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& target,+    typename timer_queue<Time_Traits>::per_timer_data& source) {   mutex::scoped_lock lock(mutex_);   op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/epoll_reactor.ipp view
@@ -2,7 +2,7 @@ // detail/impl/epoll_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,7 +21,6 @@  #include <cstddef> #include <sys/epoll.h>-#include "asio/config.hpp" #include "asio/detail/epoll_reactor.hpp" #include "asio/detail/scheduler.hpp" #include "asio/detail/throw_error.hpp"@@ -39,19 +38,13 @@ epoll_reactor::epoll_reactor(asio::execution_context& ctx)   : execution_context_service_base<epoll_reactor>(ctx),     scheduler_(use_service<scheduler>(ctx)),-    mutex_(config(ctx).get("reactor", "registration_locking", true),-        config(ctx).get("reactor", "registration_locking_spin_count", 0)),+    mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(+          REACTOR_REGISTRATION, scheduler_.concurrency_hint())),     interrupter_(),     epoll_fd_(do_epoll_create()),     timer_fd_(do_timerfd_create()),     shutdown_(false),-    io_locking_(config(ctx).get("reactor", "io_locking", true)),-    io_locking_spin_count_(-        config(ctx).get("reactor", "io_locking_spin_count", 0)),-    registered_descriptors_mutex_(mutex_.enabled(), mutex_.spin_count()),-    registered_descriptors_(execution_context::allocator<void>(ctx),-        config(ctx).get("reactor", "preallocated_io_objects", 0U),-        io_locking_, io_locking_spin_count_)+    registered_descriptors_mutex_(mutex_.enabled()) {   // Add the interrupter's descriptor to epoll.   epoll_event ev = { 0, { 0 } };@@ -137,18 +130,14 @@     for (descriptor_state* state = registered_descriptors_.first();         state != 0; state = state->next_)     {-      if (state->registered_events_ != 0)+      ev.events = state->registered_events_;+      ev.data.ptr = state;+      int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, state->descriptor_, &ev);+      if (result != 0)       {-        ev.events = state->registered_events_;-        ev.data.ptr = state;-        int result = epoll_ctl(epoll_fd_,-            EPOLL_CTL_ADD, state->descriptor_, &ev);-        if (result != 0)-        {-          asio::error_code ec(errno,-              asio::error::get_system_category());-          asio::detail::throw_error(ec, "epoll re-registration");-        }+        asio::error_code ec(errno,+            asio::error::get_system_category());+        asio::detail::throw_error(ec, "epoll re-registration");       }     }   }@@ -227,11 +216,7 @@   ev.data.ptr = descriptor_data;   int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);   if (result != 0)-  {-    // Don't try to re-register internal descriptor after fork().-    descriptor_data->registered_events_ = 0;     return errno;-  }    return 0; }@@ -678,7 +663,8 @@ epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state() {   mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);-  return registered_descriptors_.alloc(io_locking_, io_locking_spin_count_);+  return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING(+        REACTOR_IO, scheduler_.concurrency_hint())); }  void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s)@@ -770,9 +756,9 @@   operation* first_op_; }; -epoll_reactor::descriptor_state::descriptor_state(bool locking, int spin_count)+epoll_reactor::descriptor_state::descriptor_state(bool locking)   : operation(&epoll_reactor::descriptor_state::do_complete),-    mutex_(locking, spin_count)+    mutex_(locking) { } 
link/modules/asio-standalone/asio/include/asio/detail/impl/eventfd_select_interrupter.ipp view
@@ -2,7 +2,7 @@ // detail/impl/eventfd_select_interrupter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/impl/handler_tracking.ipp view
@@ -2,7 +2,7 @@ // detail/impl/handler_tracking.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -25,11 +25,16 @@  #include <cstdarg> #include <cstdio>-#include "asio/detail/chrono.hpp"-#include "asio/detail/chrono_time_traits.hpp" #include "asio/detail/handler_tracking.hpp"-#include "asio/wait_traits.hpp" +#if defined(ASIO_HAS_BOOST_DATE_TIME)+# include "asio/time_traits.hpp"+#elif defined(ASIO_HAS_CHRONO)+# include "asio/detail/chrono.hpp"+# include "asio/detail/chrono_time_traits.hpp"+# include "asio/wait_traits.hpp"+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ #if defined(ASIO_WINDOWS_RUNTIME) # include "asio/detail/socket_types.hpp" #elif !defined(ASIO_WINDOWS)@@ -48,10 +53,16 @@    handler_tracking_timestamp()   {+#if defined(ASIO_HAS_BOOST_DATE_TIME)+    boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));+    boost::posix_time::time_duration now =+      boost::posix_time::microsec_clock::universal_time() - epoch;+#elif defined(ASIO_HAS_CHRONO)     typedef chrono_time_traits<chrono::system_clock,-        asio::wait_traits<chrono::system_clock>> traits_helper;+        asio::wait_traits<chrono::system_clock> > traits_helper;     traits_helper::posix_time_duration now(         chrono::system_clock::now().time_since_epoch());+#endif     seconds = static_cast<uint64_t>(now.total_seconds());     microseconds = static_cast<uint64_t>(now.total_microseconds() % 1000000);   }
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_descriptor_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/io_uring_descriptor_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -50,7 +50,7 @@ void io_uring_descriptor_service::move_construct(     io_uring_descriptor_service::implementation_type& impl,     io_uring_descriptor_service::implementation_type& other_impl)-  noexcept+  ASIO_NOEXCEPT {   impl.descriptor_ = other_impl.descriptor_;   other_impl.descriptor_ = -1;
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_file_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/io_uring_file_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_service.hpp view
@@ -2,7 +2,7 @@ // detail/impl/io_uring_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -30,26 +30,22 @@   scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void io_uring_service::add_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void io_uring_service::add_timer_queue(timer_queue<Time_Traits>& queue) {   do_add_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void io_uring_service::remove_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void io_uring_service::remove_timer_queue(timer_queue<Time_Traits>& queue) {   do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void io_uring_service::schedule_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    const typename TimeTraits::time_type& time,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-    wait_op* op)+template <typename Time_Traits>+void io_uring_service::schedule_timer(timer_queue<Time_Traits>& queue,+    const typename Time_Traits::time_type& time,+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) {   mutex::scoped_lock lock(mutex_); @@ -68,10 +64,9 @@   } } -template <typename TimeTraits, typename Allocator>-std::size_t io_uring_service::cancel_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t io_uring_service::cancel_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& timer,     std::size_t max_cancelled) {   mutex::scoped_lock lock(mutex_);@@ -82,10 +77,9 @@   return n; } -template <typename TimeTraits, typename Allocator>-void io_uring_service::cancel_timer_by_key(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void io_uring_service::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data* timer,     void* cancellation_key) {   mutex::scoped_lock lock(mutex_);@@ -95,10 +89,10 @@   scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void io_uring_service::move_timer(timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void io_uring_service::move_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& target,+    typename timer_queue<Time_Traits>::per_timer_data& source) {   mutex::scoped_lock lock(mutex_);   op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/io_uring_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -35,21 +35,15 @@ io_uring_service::io_uring_service(asio::execution_context& ctx)   : execution_context_service_base<io_uring_service>(ctx),     scheduler_(use_service<scheduler>(ctx)),-    mutex_(config(ctx).get("reactor", "registration_locking", true),-        config(ctx).get("reactor", "registration_locking_spin_count", 0)),+    mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(+          REACTOR_REGISTRATION, scheduler_.concurrency_hint())),     outstanding_work_(0),     submit_sqes_op_(this),     pending_sqes_(0),     pending_submit_sqes_op_(false),     shutdown_(false),-    io_locking_(config(ctx).get("reactor", "io_locking", true)),-    io_locking_spin_count_(-        config(ctx).get("reactor", "io_locking_spin_count", 0)),     timeout_(),     registration_mutex_(mutex_.enabled()),-    registered_io_objects_(execution_context::allocator<void>(ctx),-        config(ctx).get("reactor", "preallocated_io_objects", 0U),-        io_locking_, io_locking_spin_count_),     reactor_(use_service<reactor>(ctx)),     reactor_data_(),     event_fd_(-1)@@ -441,16 +435,15 @@     ? ::io_uring_peek_cqe(&ring_, &cqe)     : ::io_uring_wait_cqe(&ring_, &cqe); -  if (local_ops > 0)+  if (result == 0 && usec > 0)   {-    if (result != 0 || ::io_uring_cqe_get_data(cqe) != &ts)+    if (::io_uring_cqe_get_data(cqe) != &ts)     {       mutex::scoped_lock lock(mutex_);       if (::io_uring_sqe* sqe = get_sqe())       {         ++local_ops;         ::io_uring_prep_timeout_remove(sqe, reinterpret_cast<__u64>(&ts), 0);-        ::io_uring_sqe_set_data(sqe, &ts);         submit_sqes();       }     }@@ -458,41 +451,37 @@    bool check_timers = false;   int count = 0;-  while (result == 0 || local_ops > 0)+  while (result == 0)   {-    if (result == 0)+    if (void* ptr = ::io_uring_cqe_get_data(cqe))     {-      if (void* ptr = ::io_uring_cqe_get_data(cqe))+      if (ptr == this)       {-        if (ptr == this)-        {-          // The io_uring service was interrupted.-        }-        else if (ptr == &timer_queues_)-        {-          check_timers = true;-        }-        else if (ptr == &timeout_)-        {-          check_timers = true;-          timeout_.tv_sec = 0;-          timeout_.tv_nsec = 0;-        }-        else if (ptr == &ts)-        {-          --local_ops;-        }-        else-        {-          io_queue* io_q = static_cast<io_queue*>(ptr);-          io_q->set_result(cqe->res);-          ops.push(io_q);-        }+        // The io_uring service was interrupted.       }-      ::io_uring_cqe_seen(&ring_, cqe);-      ++count;+      else if (ptr == &timer_queues_)+      {+        check_timers = true;+      }+      else if (ptr == &timeout_)+      {+        check_timers = true;+        timeout_.tv_sec = 0;+        timeout_.tv_nsec = 0;+      }+      else if (ptr == &ts)+      {+        --local_ops;+      }+      else+      {+        io_queue* io_q = static_cast<io_queue*>(ptr);+        io_q->set_result(cqe->res);+        ops.push(io_q);+      }     }-    result = (count < complete_batch_size || local_ops > 0)+    ::io_uring_cqe_seen(&ring_, cqe);+    result = (++count < complete_batch_size || local_ops > 0)       ? ::io_uring_peek_cqe(&ring_, &cqe) : -EAGAIN;   } @@ -618,7 +607,9 @@ io_uring_service::io_object* io_uring_service::allocate_io_object() {   mutex::scoped_lock registration_lock(registration_mutex_);-  return registered_io_objects_.alloc(io_locking_, io_locking_spin_count_);+  return registered_io_objects_.alloc(+      ASIO_CONCURRENCY_HINT_IS_LOCKING(+        REACTOR_IO, scheduler_.concurrency_hint())); }  void io_uring_service::free_io_object(io_uring_service::io_object* io_obj)@@ -903,8 +894,8 @@   } } -io_uring_service::io_object::io_object(bool locking, int spin_count)-  : mutex_(locking, spin_count)+io_uring_service::io_object::io_object(bool locking)+  : mutex_(locking) { } 
link/modules/asio-standalone/asio/include/asio/detail/impl/io_uring_socket_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -48,7 +48,7 @@ void io_uring_socket_service_base::base_move_construct(     io_uring_socket_service_base::base_implementation_type& impl,     io_uring_socket_service_base::base_implementation_type& other_impl)-  noexcept+  ASIO_NOEXCEPT {   impl.socket_ = other_impl.socket_;   other_impl.socket_ = invalid_socket;
link/modules/asio-standalone/asio/include/asio/detail/impl/kqueue_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/impl/kqueue_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -33,25 +33,23 @@   scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void kqueue_reactor::add_timer_queue(timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void kqueue_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) {   do_add_timer_queue(queue); }  // Remove a timer queue from the reactor.-template <typename TimeTraits, typename Allocator>-void kqueue_reactor::remove_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void kqueue_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) {   do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void kqueue_reactor::schedule_timer(timer_queue<TimeTraits, Allocator>& queue,-    const typename TimeTraits::time_type& time,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-    wait_op* op)+template <typename Time_Traits>+void kqueue_reactor::schedule_timer(timer_queue<Time_Traits>& queue,+    const typename Time_Traits::time_type& time,+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) {   mutex::scoped_lock lock(mutex_); @@ -67,10 +65,9 @@     interrupt(); } -template <typename TimeTraits, typename Allocator>-std::size_t kqueue_reactor::cancel_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t kqueue_reactor::cancel_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& timer,     std::size_t max_cancelled) {   mutex::scoped_lock lock(mutex_);@@ -81,10 +78,9 @@   return n; } -template <typename TimeTraits, typename Allocator>-void kqueue_reactor::cancel_timer_by_key(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void kqueue_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data* timer,     void* cancellation_key) {   mutex::scoped_lock lock(mutex_);@@ -94,10 +90,10 @@   scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void kqueue_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void kqueue_reactor::move_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& target,+    typename timer_queue<Time_Traits>::per_timer_data& source) {   mutex::scoped_lock lock(mutex_);   op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/kqueue_reactor.ipp view
@@ -2,7 +2,7 @@ // detail/impl/kqueue_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -20,7 +20,6 @@  #if defined(ASIO_HAS_KQUEUE) -#include "asio/config.hpp" #include "asio/detail/kqueue_reactor.hpp" #include "asio/detail/scheduler.hpp" #include "asio/detail/throw_error.hpp"@@ -47,18 +46,12 @@ kqueue_reactor::kqueue_reactor(asio::execution_context& ctx)   : execution_context_service_base<kqueue_reactor>(ctx),     scheduler_(use_service<scheduler>(ctx)),-    mutex_(config(ctx).get("reactor", "registration_locking", true),-        config(ctx).get("reactor", "registration_locking_spin_count", 0)),+    mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(+          REACTOR_REGISTRATION, scheduler_.concurrency_hint())),     kqueue_fd_(do_kqueue_create()),     interrupter_(),     shutdown_(false),-    io_locking_(config(ctx).get("reactor", "io_locking", true)),-    io_locking_spin_count_(-        config(ctx).get("reactor", "io_locking_spin_count", 0)),-    registered_descriptors_mutex_(mutex_.enabled()),-    registered_descriptors_(execution_context::allocator<void>(ctx),-        config(ctx).get("reactor", "preallocated_io_objects", 0U),-        io_locking_, io_locking_spin_count_)+    registered_descriptors_mutex_(mutex_.enabled()) {   struct kevent events[1];   ASIO_KQUEUE_EV_SET(&events[0], interrupter_.read_descriptor(),@@ -569,7 +562,8 @@ kqueue_reactor::descriptor_state* kqueue_reactor::allocate_descriptor_state() {   mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);-  return registered_descriptors_.alloc(io_locking_, io_locking_spin_count_);+  return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING(+        REACTOR_IO, scheduler_.concurrency_hint())); }  void kqueue_reactor::free_descriptor_state(kqueue_reactor::descriptor_state* s)
link/modules/asio-standalone/asio/include/asio/detail/impl/null_event.ipp view
@@ -2,7 +2,7 @@ // detail/impl/null_event.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/pipe_select_interrupter.ipp view
@@ -2,7 +2,7 @@ // detail/impl/pipe_select_interrupter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_event.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_event.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_mutex.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_mutex.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_serial_port_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_serial_port_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_thread.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_thread.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -30,17 +30,16 @@  posix_thread::~posix_thread() {-  if (arg_)-    std::terminate();+  if (!joined_)+    ::pthread_detach(thread_); }  void posix_thread::join() {-  if (arg_)+  if (!joined_)   {-    ::pthread_join(arg_->thread_, 0);-    arg_->destroy();-    arg_ = 0;+    ::pthread_join(thread_, 0);+    joined_ = true;   } } @@ -54,23 +53,24 @@   return 0; } -posix_thread::func_base* posix_thread::start_thread(func_base* arg)+void posix_thread::start_thread(func_base* arg) {-  int error = ::pthread_create(&arg->thread_, 0,+  int error = ::pthread_create(&thread_, 0,         asio_detail_posix_thread_function, arg);   if (error != 0)   {-    arg->destroy();+    delete arg;     asio::error_code ec(error,         asio::error::get_system_category());     asio::detail::throw_error(ec, "thread");   }-  return arg; }  void* asio_detail_posix_thread_function(void* arg) {-  static_cast<posix_thread::func_base*>(arg)->run();+  posix_thread::auto_func_base_ptr func = {+      static_cast<posix_thread::func_base*>(arg) };+  func.ptr->run();   return 0; } 
link/modules/asio-standalone/asio/include/asio/detail/impl/posix_tss_ptr.ipp view
@@ -2,7 +2,7 @@ // detail/impl/posix_tss_ptr.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/reactive_descriptor_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/reactive_descriptor_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -53,7 +53,7 @@ void reactive_descriptor_service::move_construct(     reactive_descriptor_service::implementation_type& impl,     reactive_descriptor_service::implementation_type& other_impl)-  noexcept+  ASIO_NOEXCEPT {   impl.descriptor_ = other_impl.descriptor_;   other_impl.descriptor_ = -1;@@ -198,20 +198,18 @@ }  void reactive_descriptor_service::do_start_op(implementation_type& impl,-    int op_type, reactor_op* op, bool is_continuation,-    bool allow_speculative, bool noop, bool needs_non_blocking,-    void (*on_immediate)(operation* op, bool, const void*),+    int op_type, reactor_op* op, bool is_continuation, bool is_non_blocking,+    bool noop, void (*on_immediate)(operation* op, bool, const void*),     const void* immediate_arg) {   if (!noop)   {-    if ((impl.state_ & descriptor_ops::non_blocking)-        || !needs_non_blocking-        || descriptor_ops::set_internal_non_blocking(+    if ((impl.state_ & descriptor_ops::non_blocking) ||+        descriptor_ops::set_internal_non_blocking(           impl.descriptor_, impl.state_, true, op->ec_))     {       reactor_.start_op(op_type, impl.descriptor_, impl.reactor_data_, op,-          is_continuation, allow_speculative, on_immediate, immediate_arg);+          is_continuation, is_non_blocking, on_immediate, immediate_arg);       return;     }   }
link/modules/asio-standalone/asio/include/asio/detail/impl/reactive_socket_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -50,7 +50,7 @@ void reactive_socket_service_base::base_move_construct(     reactive_socket_service_base::base_implementation_type& impl,     reactive_socket_service_base::base_implementation_type& other_impl)-  noexcept+  ASIO_NOEXCEPT {   impl.socket_ = other_impl.socket_;   other_impl.socket_ = invalid_socket;@@ -234,21 +234,19 @@ }  void reactive_socket_service_base::do_start_op(-    reactive_socket_service_base::base_implementation_type& impl,-    int op_type, reactor_op* op, bool is_continuation,-    bool allow_speculative, bool noop, bool needs_non_blocking,+    reactive_socket_service_base::base_implementation_type& impl, int op_type,+    reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop,     void (*on_immediate)(operation* op, bool, const void*),     const void* immediate_arg) {   if (!noop)   {     if ((impl.state_ & socket_ops::non_blocking)-        || !needs_non_blocking         || socket_ops::set_internal_non_blocking(           impl.socket_, impl.state_, true, op->ec_))     {       reactor_.start_op(op_type, impl.socket_, impl.reactor_data_, op,-          is_continuation, allow_speculative, on_immediate, immediate_arg);+          is_continuation, is_non_blocking, on_immediate, immediate_arg);       return;     }   }@@ -265,7 +263,7 @@   if (!peer_is_open)   {     do_start_op(impl, reactor::read_op, op, is_continuation,-        true, false, true, on_immediate, immediate_arg);+        true, false, on_immediate, immediate_arg);   }   else   {
link/modules/asio-standalone/asio/include/asio/detail/impl/resolver_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/impl/resolver_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,8 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include "asio/config.hpp"-#include "asio/detail/memory.hpp" #include "asio/detail/resolver_service_base.hpp"  #include "asio/detail/push_options.hpp"@@ -25,15 +23,70 @@ namespace asio { namespace detail { +class resolver_service_base::work_scheduler_runner+{+public:+  work_scheduler_runner(scheduler_impl& work_scheduler)+    : work_scheduler_(work_scheduler)+  {+  }++  void operator()()+  {+    asio::error_code ec;+    work_scheduler_.run(ec);+  }++private:+  scheduler_impl& work_scheduler_;+};+ resolver_service_base::resolver_service_base(execution_context& context)-  : thread_pool_(asio::use_service<resolver_thread_pool>(context))+  : scheduler_(asio::use_service<scheduler_impl>(context)),+    work_scheduler_(new scheduler_impl(context, -1, false)),+    work_thread_(0) {+  work_scheduler_->work_started(); }  resolver_service_base::~resolver_service_base() {+  base_shutdown(); } +void resolver_service_base::base_shutdown()+{+  if (work_scheduler_.get())+  {+    work_scheduler_->work_finished();+    work_scheduler_->stop();+    if (work_thread_.get())+    {+      work_thread_->join();+      work_thread_.reset();+    }+    work_scheduler_.reset();+  }+}++void resolver_service_base::base_notify_fork(+    execution_context::fork_event fork_ev)+{+  if (work_thread_.get())+  {+    if (fork_ev == execution_context::fork_prepare)+    {+      work_scheduler_->stop();+      work_thread_->join();+      work_thread_.reset();+    }+  }+  else if (fork_ev != execution_context::fork_prepare)+  {+    work_scheduler_->restart();+  }+}+ void resolver_service_base::construct(     resolver_service_base::implementation_type& impl) {@@ -43,7 +96,7 @@ void resolver_service_base::destroy(     resolver_service_base::implementation_type& impl) {-  ASIO_HANDLER_OPERATION((thread_pool_.context(),+  ASIO_HANDLER_OPERATION((scheduler_.context(),         "resolver", &impl, 0, "cancel"));    impl.reset();@@ -52,23 +105,49 @@ void resolver_service_base::move_construct(implementation_type& impl,     implementation_type& other_impl) {-  impl = static_cast<implementation_type&&>(other_impl);+  impl = ASIO_MOVE_CAST(implementation_type)(other_impl); }  void resolver_service_base::move_assign(implementation_type& impl,     resolver_service_base&, implementation_type& other_impl) {   destroy(impl);-  impl = static_cast<implementation_type&&>(other_impl);+  impl = ASIO_MOVE_CAST(implementation_type)(other_impl); }  void resolver_service_base::cancel(     resolver_service_base::implementation_type& impl) {-  ASIO_HANDLER_OPERATION((thread_pool_.context(),+  ASIO_HANDLER_OPERATION((scheduler_.context(),         "resolver", &impl, 0, "cancel"));    impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());+}++void resolver_service_base::start_resolve_op(resolve_op* op)+{+  if (ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,+        scheduler_.concurrency_hint()))+  {+    start_work_thread();+    scheduler_.work_started();+    work_scheduler_->post_immediate_completion(op, false);+  }+  else+  {+    op->ec_ = asio::error::operation_not_supported;+    scheduler_.post_immediate_completion(op, false);+  }+}++void resolver_service_base::start_work_thread()+{+  asio::detail::mutex::scoped_lock lock(mutex_);+  if (!work_thread_.get())+  {+    work_thread_.reset(new asio::detail::thread(+          work_scheduler_runner(*work_scheduler_)));+  } }  } // namespace detail
− link/modules/asio-standalone/asio/include/asio/detail/impl/resolver_thread_pool.ipp
@@ -1,124 +0,0 @@-//-// detail/impl/resolver_thread_pool.ipp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DETAIL_IMPL_RESOLVER_THREAD_POOL_IPP-#define ASIO_DETAIL_IMPL_RESOLVER_THREAD_POOL_IPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/config.hpp"-#include "asio/detail/memory.hpp"-#include "asio/detail/resolver_thread_pool.hpp"-#include "asio/error.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--class resolver_thread_pool::work_scheduler_runner-{-public:-  work_scheduler_runner(scheduler_impl& work_scheduler)-    : work_scheduler_(work_scheduler)-  {-  }--  void operator()()-  {-    asio::error_code ec;-    work_scheduler_.run(ec);-  }--private:-  scheduler_impl& work_scheduler_;-};--resolver_thread_pool::resolver_thread_pool(execution_context& context)-  : execution_context_service_base<resolver_thread_pool>(context),-    scheduler_(asio::use_service<scheduler_impl>(context)),-    work_scheduler_(scheduler_impl::internal(), context),-    work_threads_(execution_context::allocator<void>(context)),-    num_work_threads_(config(context).get("resolver", "threads", 0U)),-    scheduler_locking_(config(context).get("scheduler", "locking", true)),-    shutdown_(false)-{-  work_scheduler_.work_started();-  if (num_work_threads_ > 0)-    start_work_threads();-  else-    num_work_threads_ = 1;-}--resolver_thread_pool::~resolver_thread_pool()-{-  shutdown();-}--void resolver_thread_pool::shutdown()-{-  if (!shutdown_)-  {-    work_scheduler_.work_finished();-    work_scheduler_.stop();-    work_threads_.join();-    work_scheduler_.shutdown();-    shutdown_ = true;-  }-}--void resolver_thread_pool::notify_fork(execution_context::fork_event fork_ev)-{-  if (!work_threads_.empty())-  {-    if (fork_ev == execution_context::fork_prepare)-    {-      work_scheduler_.stop();-      work_threads_.join();-    }-  }-  else if (fork_ev != execution_context::fork_prepare)-  {-    work_scheduler_.restart();-  }-}--void resolver_thread_pool::start_resolve_op(resolve_op* op)-{-  if (scheduler_locking_)-  {-    start_work_threads();-    scheduler_.work_started();-    work_scheduler_.post_immediate_completion(op, false);-  }-  else-  {-    op->ec_ = asio::error::operation_not_supported;-    scheduler_.post_immediate_completion(op, false);-  }-}--void resolver_thread_pool::start_work_threads()-{-  asio::detail::mutex::scoped_lock lock(mutex_);-  if (work_threads_.empty())-    for (unsigned int i = 0; i < num_work_threads_; ++i)-      work_threads_.create_thread(work_scheduler_runner(work_scheduler_));-}--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_IMPL_RESOLVER_THREAD_POOL_IPP
link/modules/asio-standalone/asio/include/asio/detail/impl/scheduler.ipp view
@@ -2,7 +2,7 @@ // detail/impl/scheduler.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,7 +17,7 @@  #include "asio/detail/config.hpp" -#include "asio/config.hpp"+#include "asio/detail/concurrency_hint.hpp" #include "asio/detail/event.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/scheduler.hpp"@@ -109,56 +109,44 @@ };  scheduler::scheduler(asio::execution_context& ctx,-    bool own_thread, get_task_func_type get_task)+    int concurrency_hint, bool own_thread, get_task_func_type get_task)   : asio::detail::execution_context_service_base<scheduler>(ctx),-    one_thread_(config(ctx).get("scheduler", "concurrency_hint", 0) == 1),-    mutex_(config(ctx).get("scheduler", "locking", true),-        config(ctx).get("scheduler", "locking_spin_count", 0)),+    one_thread_(concurrency_hint == 1+        || !ASIO_CONCURRENCY_HINT_IS_LOCKING(+          SCHEDULER, concurrency_hint)+        || !ASIO_CONCURRENCY_HINT_IS_LOCKING(+          REACTOR_IO, concurrency_hint)),+    mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(+          SCHEDULER, concurrency_hint)),     task_(0),     get_task_(get_task),     task_interrupted_(true),+    outstanding_work_(0),     stopped_(false),     shutdown_(false),-    outstanding_work_(0),-    task_usec_(config(ctx).get("scheduler", "task_usec", -1L)),-    wait_usec_(config(ctx).get("scheduler", "wait_usec", -1L)),-    thread_()+    concurrency_hint_(concurrency_hint),+    thread_(0) {   ASIO_HANDLER_TRACKING_INIT;    if (own_thread)   {     ++outstanding_work_;-    signal_blocker sb;-    thread_ = thread(thread_function(this));+    asio::detail::signal_blocker sb;+    thread_ = new asio::detail::thread(thread_function(this));   } } -scheduler::scheduler(scheduler::internal, asio::execution_context& ctx)-  : asio::detail::execution_context_service_base<scheduler>(ctx),-    one_thread_(false),-    mutex_(true, 0),-    task_(0),-    get_task_(&scheduler::get_default_task),-    task_interrupted_(true),-    stopped_(false),-    shutdown_(false),-    outstanding_work_(0),-    task_usec_(-1L),-    wait_usec_(-1L)-{-  ASIO_HANDLER_TRACKING_INIT;-}- scheduler::~scheduler() {-  if (thread_.joinable())+  if (thread_)   {     mutex::scoped_lock lock(mutex_);     shutdown_ = true;     stop_all_threads(lock);     lock.unlock();-    thread_.join();+    thread_->join();+    delete thread_;   } } @@ -166,12 +154,17 @@ {   mutex::scoped_lock lock(mutex_);   shutdown_ = true;-  if (thread_.joinable())+  if (thread_)     stop_all_threads(lock);   lock.unlock();    // Join thread to ensure task operation is returned to queue.-  thread_.join();+  if (thread_)+  {+    thread_->join();+    delete thread_;+    thread_ = 0;+  }    // Destroy handler objects.   while (!op_queue_.empty())@@ -467,9 +460,9 @@        if (o == &task_operation_)       {-        task_interrupted_ = more_handlers || task_usec_ == 0;+        task_interrupted_ = more_handlers; -        if (more_handlers && !one_thread_ && wait_usec_ != 0)+        if (more_handlers && !one_thread_)           wakeup_event_.unlock_and_signal_one(lock);         else           lock.unlock();@@ -480,8 +473,7 @@         // Run the task. May throw an exception. Only block if the operation         // queue is empty and we're not polling, otherwise we want to return         // as soon as possible.-        task_->run(more_handlers ? 0 : task_usec_,-            this_thread.private_op_queue);+        task_->run(more_handlers ? 0 : -1, this_thread.private_op_queue);       }       else       {@@ -505,19 +497,8 @@     }     else     {-      if (wait_usec_ == 0)-      {-        lock.unlock();-        lock.lock();-      }-      else-      {-        wakeup_event_.clear(lock);-        if (wait_usec_ > 0)-          wakeup_event_.wait_for_usec(lock, wait_usec_);-        else-          wakeup_event_.wait(lock);-      }+      wakeup_event_.clear(lock);+      wakeup_event_.wait(lock);     }   } @@ -535,7 +516,6 @@   if (o == 0)   {     wakeup_event_.clear(lock);-    usec = (wait_usec_ >= 0 && wait_usec_ < usec) ? wait_usec_ : usec;     wakeup_event_.wait_for_usec(lock, usec);     usec = 0; // Wait at most once.     o = op_queue_.front();@@ -546,10 +526,9 @@     op_queue_.pop();     bool more_handlers = (!op_queue_.empty()); -    usec = (task_usec_ >= 0 && task_usec_ < usec) ? task_usec_ : usec;-    task_interrupted_ = more_handlers || usec == 0;+    task_interrupted_ = more_handlers; -    if (more_handlers && !one_thread_ && wait_usec_ != 0)+    if (more_handlers && !one_thread_)       wakeup_event_.unlock_and_signal_one(lock);     else       lock.unlock();@@ -668,7 +647,7 @@ void scheduler::wake_one_thread_and_unlock(     mutex::scoped_lock& lock) {-  if (wait_usec_ == 0 || !wakeup_event_.maybe_unlock_and_signal_one(lock))+  if (!wakeup_event_.maybe_unlock_and_signal_one(lock))   {     if (!task_interrupted_ && task_)     {
link/modules/asio-standalone/asio/include/asio/detail/impl/select_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/impl/select_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -40,27 +40,23 @@   scheduler_.post_immediate_completion(op, is_continuation); } -template <typename TimeTraits, typename Allocator>-void select_reactor::add_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void select_reactor::add_timer_queue(timer_queue<Time_Traits>& queue) {   do_add_timer_queue(queue); }  // Remove a timer queue from the reactor.-template <typename TimeTraits, typename Allocator>-void select_reactor::remove_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void select_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue) {   do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void select_reactor::schedule_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    const typename TimeTraits::time_type& time,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-    wait_op* op)+template <typename Time_Traits>+void select_reactor::schedule_timer(timer_queue<Time_Traits>& queue,+    const typename Time_Traits::time_type& time,+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) {   asio::detail::mutex::scoped_lock lock(mutex_); @@ -76,10 +72,9 @@     interrupter_.interrupt(); } -template <typename TimeTraits, typename Allocator>-std::size_t select_reactor::cancel_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t select_reactor::cancel_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& timer,     std::size_t max_cancelled) {   asio::detail::mutex::scoped_lock lock(mutex_);@@ -90,10 +85,9 @@   return n; } -template <typename TimeTraits, typename Allocator>-void select_reactor::cancel_timer_by_key(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void select_reactor::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data* timer,     void* cancellation_key) {   mutex::scoped_lock lock(mutex_);@@ -103,10 +97,10 @@   scheduler_.post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void select_reactor::move_timer(timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& source)+template <typename Time_Traits>+void select_reactor::move_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& target,+    typename timer_queue<Time_Traits>::per_timer_data& source) {   asio::detail::mutex::scoped_lock lock(mutex_);   op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/select_reactor.ipp view
@@ -2,7 +2,7 @@ // detail/impl/select_reactor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -65,14 +65,14 @@     interrupter_(), #if defined(ASIO_HAS_IOCP)     stop_thread_(false),-    thread_(),+    thread_(0),     restart_reactor_(this), #endif // defined(ASIO_HAS_IOCP)     shutdown_(false) { #if defined(ASIO_HAS_IOCP)   asio::detail::signal_blocker sb;-  thread_ = thread(thread_function(this));+  thread_ = new asio::detail::thread(thread_function(this)); #endif // defined(ASIO_HAS_IOCP) } @@ -87,13 +87,18 @@   shutdown_ = true; #if defined(ASIO_HAS_IOCP)   stop_thread_ = true;-  if (thread_.joinable())+  if (thread_)     interrupter_.interrupt(); #endif // defined(ASIO_HAS_IOCP)   lock.unlock();  #if defined(ASIO_HAS_IOCP)-  thread_.join();+  if (thread_)+  {+    thread_->join();+    delete thread_;+    thread_ = 0;+  } #endif // defined(ASIO_HAS_IOCP)    op_queue<operation> ops;@@ -325,7 +330,12 @@   {     select_reactor* reactor = static_cast<restart_reactor*>(base)->reactor_; -    reactor->thread_.join();+    if (reactor->thread_)+    {+      reactor->thread_->join();+      delete reactor->thread_;+      reactor->thread_ = 0;+    }      asio::detail::mutex::scoped_lock lock(reactor->mutex_);     reactor->interrupter_.recreate();@@ -333,7 +343,8 @@     lock.unlock();      asio::detail::signal_blocker sb;-    reactor->thread_ = thread(thread_function(reactor));+    reactor->thread_ =+      new asio::detail::thread(thread_function(reactor));   } } #endif // defined(ASIO_HAS_IOCP)
link/modules/asio-standalone/asio/include/asio/detail/impl/service_registry.hpp view
@@ -2,7 +2,7 @@ // detail/impl/service_registry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -38,18 +38,6 @@   return *static_cast<Service*>(do_use_service(key, factory, &owner)); } -template <typename Service, typename... Args>-Service& service_registry::make_service(Args&&... args)-{-  auto_service_ptr new_service =-    { create<Service, execution_context>(owner_,-        &owner_, static_cast<Args&&>(args)...) };-  add_service(static_cast<Service*>(new_service.ptr_));-  Service& result = *static_cast<Service*>(new_service.ptr_);-  new_service.ptr_ = 0;-  return result;-}- template <typename Service> void service_registry::add_service(Service* new_service) {@@ -76,7 +64,8 @@ #if !defined(ASIO_NO_TYPEID) template <typename Service> void service_registry::init_key(execution_context::service::key& key,-    enable_if_t<is_base_of<typename Service::key_type, Service>::value>*)+    typename enable_if<+      is_base_of<typename Service::key_type, Service>::value>::type*) {   key.type_info_ = &typeid(typeid_wrapper<Service>);   key.id_ = 0;@@ -91,22 +80,10 @@ } #endif // !defined(ASIO_NO_TYPEID) -template <typename Service, typename Owner, typename... Args>-execution_context::service* service_registry::create(-    execution_context& context, void* owner, Args&&... args)-{-  Service* svc = allocate_object<Service>(-      execution_context::allocator<void>(context),-      *static_cast<Owner*>(owner), static_cast<Args&&>(args)...);-  svc->destroy_ = &service_registry::destroy_allocated<Service>;-  return svc;-}--template <typename Service>-void service_registry::destroy_allocated(execution_context::service* service)+template <typename Service, typename Owner>+execution_context::service* service_registry::create(void* owner) {-  deallocate_object(execution_context::allocator<void>(service->owner_),-      static_cast<Service*>(service));+  return new Service(*static_cast<Owner*>(owner)); }  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/impl/service_registry.ipp view
@@ -2,7 +2,7 @@ // detail/impl/service_registry.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -50,7 +50,7 @@   while (first_service_)   {     execution_context::service* next_service = first_service_->next_;-    first_service_->destroy_(first_service_);+    destroy(first_service_);     first_service_ = next_service;   } }@@ -104,17 +104,11 @@   return false; } -void service_registry::destroy_added(execution_context::service* service)+void service_registry::destroy(execution_context::service* service) {   delete service; } -service_registry::auto_service_ptr::~auto_service_ptr()-{-  if (ptr_)-    ptr_->destroy_(ptr_);-}- execution_context::service* service_registry::do_use_service(     const execution_context::service::key& key,     factory_type factory, void* owner)@@ -134,7 +128,7 @@   // at this time to allow for nested calls into this function from the new   // service's constructor.   lock.unlock();-  auto_service_ptr new_service = { factory(owner_, owner) };+  auto_service_ptr new_service = { factory(owner) };   new_service.ptr_->key_ = key;   lock.lock(); @@ -174,8 +168,6 @@   }    // Take ownership of the service object.-  if (!new_service->destroy_)-    new_service->destroy_ = &service_registry::destroy_added;   new_service->key_ = key;   new_service->next_ = first_service_;   first_service_ = new_service;
link/modules/asio-standalone/asio/include/asio/detail/impl/signal_set_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/signal_set_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -386,7 +386,6 @@         if (state->flags_[signal_number] != signal_set_base::flags::dont_care)         {           ec = asio::error::invalid_argument;-          delete new_registration;           return ec;         }         struct sigaction sa;@@ -398,7 +397,6 @@         {           ec = asio::error_code(errno,               asio::error::get_system_category());-          delete new_registration;           return ec;         }         state->flags_[signal_number] = f;@@ -658,9 +656,10 @@   // scheduler used to create signal_set objects.   if (state->service_list_ != 0)   {-    if (!config(service->context()).get("scheduler", "locking", true)-        || !config(state->service_list_->context()).get(-            "scheduler", "locking", true))+    if (!ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,+          service->scheduler_.concurrency_hint())+        || !ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,+          state->service_list_->scheduler_.concurrency_hint()))     {       std::logic_error ex(           "Thread-unsafe execution context objects require "
link/modules/asio-standalone/asio/include/asio/detail/impl/socket_ops.ipp view
@@ -2,7 +2,7 @@ // detail/impl/socket_ops.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -41,10 +41,6 @@ #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)        // || defined(__MACH__) && defined(__APPLE__) -#if defined(_MSC_VER) && (_MSC_VER >= 1800)-# include <malloc.h>-#endif // defined(_MSC_VER) && (_MSC_VER >= 1800)- #include "asio/detail/push_options.hpp"  namespace asio {@@ -343,24 +339,7 @@         ::fcntl(s, F_SETFL, flags & ~O_NONBLOCK); # else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)       ioctl_arg_type arg = 0;-      if ((state & possible_dup) == 0)-      {-        result = ::ioctl(s, FIONBIO, &arg);-        get_last_error(ec, result < 0);-      }-      if ((state & possible_dup) != 0-#  if defined(ENOTTY)-          || ec.value() == ENOTTY-#  endif // defined(ENOTTY)-#  if defined(ENOTCAPABLE)-          || ec.value() == ENOTCAPABLE-#  endif // defined(ENOTCAPABLE)-        )-      {-        int flags = ::fcntl(s, F_GETFL, 0);-        if (flags >= 0)-          ::fcntl(s, F_SETFL, flags & ~O_NONBLOCK);-      }+      ::ioctl(s, FIONBIO, &arg); # endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__) #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)       state &= ~non_blocking;@@ -396,36 +375,14 @@   if (result >= 0)   {     int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));-    result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0;+    result = ::fcntl(s, F_SETFL, flag);     get_last_error(ec, result < 0);   }-#else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)+#else   ioctl_arg_type arg = (value ? 1 : 0);-  int result = 0;-  if ((state & possible_dup) == 0)-  {-    result = ::ioctl(s, FIONBIO, &arg);-    get_last_error(ec, result < 0);-  }-  if ((state & possible_dup) != 0-# if defined(ENOTTY)-      || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)-      || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)-    )-  {-    result = ::fcntl(s, F_GETFL, 0);-    get_last_error(ec, result < 0);-    if (result >= 0)-    {-      int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));-      result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0;-      get_last_error(ec, result < 0);-    }-  }-#endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)+  int result = ::ioctl(s, FIONBIO, &arg);+  get_last_error(ec, result < 0);+#endif    if (result >= 0)   {@@ -472,36 +429,14 @@   if (result >= 0)   {     int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));-    result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0;+    result = ::fcntl(s, F_SETFL, flag);     get_last_error(ec, result < 0);   }-#else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)+#else   ioctl_arg_type arg = (value ? 1 : 0);-  int result = 0;-  if ((state & possible_dup) == 0)-  {-    result = ::ioctl(s, FIONBIO, &arg);-    get_last_error(ec, result < 0);-  }-  if ((state & possible_dup) != 0-# if defined(ENOTTY)-      || ec.value() == ENOTTY-# endif // defined(ENOTTY)-# if defined(ENOTCAPABLE)-      || ec.value() == ENOTCAPABLE-# endif // defined(ENOTCAPABLE)-    )-  {-    result = ::fcntl(s, F_GETFL, 0);-    get_last_error(ec, result < 0);-    if (result >= 0)-    {-      int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));-      result = (flag != result) ? ::fcntl(s, F_SETFL, flag) : 0;-      get_last_error(ec, result < 0);-    }-  }-#endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)+  int result = ::ioctl(s, FIONBIO, &arg);+  get_last_error(ec, result < 0);+#endif    if (result >= 0)   {@@ -2586,11 +2521,9 @@         || if_indextoname(static_cast<unsigned>(scope_id), if_name + 1) == 0) #if defined(ASIO_HAS_SNPRINTF)       snprintf(if_name + 1, sizeof(if_name) - 1, "%lu", scope_id);-#elif defined(ASIO_HAS_SECURE_RTL)-      sprintf_s(if_name + 1, sizeof(if_name) -1, "%lu", scope_id);-#else // defined(ASIO_HAS_SECURE_RTL)+#else // defined(ASIO_HAS_SNPRINTF)       sprintf(if_name + 1, "%lu", scope_id);-#endif // defined(ASIO_HAS_SECURE_RTL)+#endif // defined(ASIO_HAS_SNPRINTF)     strcat(dest, if_name);   }   return result;
link/modules/asio-standalone/asio/include/asio/detail/impl/socket_select_interrupter.ipp view
@@ -2,7 +2,7 @@ // detail/impl/socket_select_interrupter.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -90,7 +90,7 @@   socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec));   if (server.get() == invalid_socket)     asio::detail::throw_error(ec, "socket_select_interrupter");-+     ioctl_arg_type non_blocking = 1;   socket_ops::state_type client_state = 0;   if (socket_ops::ioctl(client.get(), client_state,
link/modules/asio-standalone/asio/include/asio/detail/impl/strand_executor_service.hpp view
@@ -2,7 +2,7 @@ // detail/impl/strand_executor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/fenced_block.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/recycling_allocator.hpp" #include "asio/executor_work_guard.hpp" #include "asio/defer.hpp"@@ -33,8 +34,8 @@ public:   typedef Allocator allocator_type; -  allocator_binder(F&& f, const Allocator& a)-    : f_(static_cast<F&&>(f)),+  allocator_binder(ASIO_MOVE_ARG(F) f, const Allocator& a)+    : f_(ASIO_MOVE_CAST(F)(f)),       allocator_(a)   {   }@@ -45,13 +46,15 @@   {   } +#if defined(ASIO_HAS_MOVE)   allocator_binder(allocator_binder&& other)-    : f_(static_cast<F&&>(other.f_)),-      allocator_(static_cast<allocator_type&&>(other.allocator_))+    : f_(ASIO_MOVE_CAST(F)(other.f_)),+      allocator_(ASIO_MOVE_CAST(allocator_type)(other.allocator_))   {   }+#endif // defined(ASIO_HAS_MOVE) -  allocator_type get_allocator() const noexcept+  allocator_type get_allocator() const ASIO_NOEXCEPT   {     return allocator_;   }@@ -68,9 +71,9 @@  template <typename Executor> class strand_executor_service::invoker<Executor,-    enable_if_t<+    typename enable_if<       execution::is_executor<Executor>::value-    >>+    >::type> { public:   invoker(const implementation_type& impl, Executor& ex)@@ -85,11 +88,13 @@   {   } +#if defined(ASIO_HAS_MOVE)   invoker(invoker&& other)-    : impl_(static_cast<implementation_type&&>(other.impl_)),-      executor_(static_cast<executor_type&&>(other.executor_))+    : impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)),+      executor_(ASIO_MOVE_CAST(executor_type)(other.executor_))   {   }+#endif // defined(ASIO_HAS_MOVE)    struct on_invoker_exit   {@@ -101,12 +106,22 @@       {         recycling_allocator<void> allocator;         executor_type ex = this_->executor_;+#if defined(ASIO_NO_DEPRECATED)         asio::prefer(             asio::require(-              static_cast<executor_type&&>(ex),+              ASIO_MOVE_CAST(executor_type)(ex),               execution::blocking.never),             execution::allocator(allocator)-          ).execute(static_cast<invoker&&>(*this_));+          ).execute(ASIO_MOVE_CAST(invoker)(*this_));+#else // defined(ASIO_NO_DEPRECATED)+        execution::execute(+            asio::prefer(+              asio::require(+                ASIO_MOVE_CAST(executor_type)(ex),+                execution::blocking.never),+              execution::allocator(allocator)),+            ASIO_MOVE_CAST(invoker)(*this_));+#endif // defined(ASIO_NO_DEPRECATED)       }     }   };@@ -121,12 +136,12 @@   }  private:-  typedef decay_t<-      prefer_result_t<+  typedef typename decay<+      typename prefer_result<         Executor,         execution::outstanding_work_t::tracked_t-      >-    > executor_type;+      >::type+    >::type executor_type;    implementation_type impl_;   executor_type executor_;@@ -136,9 +151,9 @@  template <typename Executor> class strand_executor_service::invoker<Executor,-    enable_if_t<+    typename enable_if<       !execution::is_executor<Executor>::value-    >>+    >::type> { public:   invoker(const implementation_type& impl, Executor& ex)@@ -153,11 +168,13 @@   {   } +#if defined(ASIO_HAS_MOVE)   invoker(invoker&& other)-    : impl_(static_cast<implementation_type&&>(other.impl_)),-      work_(static_cast<executor_work_guard<Executor>&&>(other.work_))+    : impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_)),+      work_(ASIO_MOVE_CAST(executor_work_guard<Executor>)(other.work_))   {   }+#endif // defined(ASIO_HAS_MOVE)    struct on_invoker_exit   {@@ -169,7 +186,7 @@       {         Executor ex(this_->work_.get_executor());         recycling_allocator<void> allocator;-        ex.post(static_cast<invoker&&>(*this_), allocator);+        ex.post(ASIO_MOVE_CAST(invoker)(*this_), allocator);       }     }   };@@ -192,33 +209,33 @@  template <typename Executor, typename Function> inline void strand_executor_service::execute(const implementation_type& impl,-    Executor& ex, Function&& function,-    enable_if_t<-      can_query<Executor, execution::allocator_t<void>>::value-    >*)+    Executor& ex, ASIO_MOVE_ARG(Function) function,+    typename enable_if<+      can_query<Executor, execution::allocator_t<void> >::value+    >::type*) {   return strand_executor_service::do_execute(impl, ex,-      static_cast<Function&&>(function),+      ASIO_MOVE_CAST(Function)(function),       asio::query(ex, execution::allocator)); }  template <typename Executor, typename Function> inline void strand_executor_service::execute(const implementation_type& impl,-    Executor& ex, Function&& function,-    enable_if_t<-      !can_query<Executor, execution::allocator_t<void>>::value-    >*)+    Executor& ex, ASIO_MOVE_ARG(Function) function,+    typename enable_if<+      !can_query<Executor, execution::allocator_t<void> >::value+    >::type*) {   return strand_executor_service::do_execute(impl, ex,-      static_cast<Function&&>(function),+      ASIO_MOVE_CAST(Function)(function),       std::allocator<void>()); }  template <typename Executor, typename Function, typename Allocator> void strand_executor_service::do_execute(const implementation_type& impl,-    Executor& ex, Function&& function, const Allocator& a)+    Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // If the executor is not never-blocking, and we are already in the strand,   // then the function can run immediately.@@ -226,17 +243,17 @@       && running_in_this_thread(impl))   {     // Make a local, non-const copy of the function.-    function_type tmp(static_cast<Function&&>(function));+    function_type tmp(ASIO_MOVE_CAST(Function)(function));      fenced_block b(fenced_block::full);-    static_cast<function_type&&>(tmp)();+    asio_handler_invoke_helpers::invoke(tmp, tmp);     return;   }    // Allocate and construct an operation to wrap the function.   typedef executor_op<function_type, Allocator> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(function), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a);    ASIO_HANDLER_CREATION((impl->service_->context(), *p.p,         "strand_executor", impl.get(), 0, "execute"));@@ -246,31 +263,35 @@   p.v = p.p = 0;   if (first)   {+#if defined(ASIO_NO_DEPRECATED)     ex.execute(invoker<Executor>(impl, ex));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(ex, invoker<Executor>(impl, ex));+#endif // defined(ASIO_NO_DEPRECATED)   } }  template <typename Executor, typename Function, typename Allocator> void strand_executor_service::dispatch(const implementation_type& impl,-    Executor& ex, Function&& function, const Allocator& a)+    Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // If we are already in the strand then the function can run immediately.   if (running_in_this_thread(impl))   {     // Make a local, non-const copy of the function.-    function_type tmp(static_cast<Function&&>(function));+    function_type tmp(ASIO_MOVE_CAST(Function)(function));      fenced_block b(fenced_block::full);-    static_cast<function_type&&>(tmp)();+    asio_handler_invoke_helpers::invoke(tmp, tmp);     return;   }    // Allocate and construct an operation to wrap the function.   typedef executor_op<function_type, Allocator> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(function), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a);    ASIO_HANDLER_CREATION((impl->service_->context(), *p.p,         "strand_executor", impl.get(), 0, "dispatch"));@@ -289,14 +310,14 @@ // Request invocation of the given function and return immediately. template <typename Executor, typename Function, typename Allocator> void strand_executor_service::post(const implementation_type& impl,-    Executor& ex, Function&& function, const Allocator& a)+    Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // Allocate and construct an operation to wrap the function.   typedef executor_op<function_type, Allocator> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(function), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a);    ASIO_HANDLER_CREATION((impl->service_->context(), *p.p,         "strand_executor", impl.get(), 0, "post"));@@ -315,14 +336,14 @@ // Request invocation of the given function and return immediately. template <typename Executor, typename Function, typename Allocator> void strand_executor_service::defer(const implementation_type& impl,-    Executor& ex, Function&& function, const Allocator& a)+    Executor& ex, ASIO_MOVE_ARG(Function) function, const Allocator& a) {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // Allocate and construct an operation to wrap the function.   typedef executor_op<function_type, Allocator> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(function), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(function), a);    ASIO_HANDLER_CREATION((impl->service_->context(), *p.p,         "strand_executor", impl.get(), 0, "defer"));
link/modules/asio-standalone/asio/include/asio/detail/impl/strand_executor_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/strand_executor_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -52,8 +52,7 @@ strand_executor_service::implementation_type strand_executor_service::create_implementation() {-  execution_context::allocator<void> alloc(context());-  implementation_type new_impl = allocate_shared<strand_impl>(alloc);+  implementation_type new_impl(new strand_impl);   new_impl->locked_ = false;   new_impl->shutdown_ = false; @@ -65,8 +64,8 @@   mutex_index += (reinterpret_cast<std::size_t>(new_impl.get()) >> 3);   mutex_index ^= salt + 0x9e3779b9 + (mutex_index << 6) + (mutex_index >> 2);   mutex_index = mutex_index % num_mutexes;-  if (!mutexes_[mutex_index])-    mutexes_[mutex_index] = allocate_shared<mutex>(alloc);+  if (!mutexes_[mutex_index].get())+    mutexes_[mutex_index].reset(new mutex);   new_impl->mutex_ = mutexes_[mutex_index].get();    // Insert implementation into linked list of all implementations.
link/modules/asio-standalone/asio/include/asio/detail/impl/strand_service.hpp view
@@ -2,7 +2,7 @@ // detail/impl/strand_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,7 @@ #include "asio/detail/completion_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp"  #include "asio/detail/push_options.hpp"@@ -39,7 +40,7 @@   if (running_in_this_thread(impl))   {     fenced_block b(fenced_block::full);-    static_cast<Handler&&>(handler)();+    asio_handler_invoke_helpers::invoke(handler, handler);     return;   } 
link/modules/asio-standalone/asio/include/asio/detail/impl/strand_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/strand_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -80,11 +80,8 @@ #endif // defined(ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION)   index = index % num_implementations; -  if (!implementations_[index])-  {-    execution_context::allocator<void> alloc(context());-    implementations_[index] = allocate_shared<strand_impl>(alloc);-  }+  if (!implementations_[index].get())+    implementations_[index].reset(new strand_impl);   impl = implementations_[index].get(); } 
link/modules/asio-standalone/asio/include/asio/detail/impl/thread_context.ipp view
@@ -2,7 +2,7 @@ // detail/impl/thread_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/throw_error.ipp view
@@ -2,7 +2,7 @@ // detail/impl/throw_error.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -37,8 +37,29 @@     const char* location     ASIO_SOURCE_LOCATION_PARAM) {+  // boostify: non-boost code starts here+#if defined(ASIO_MSVC) \+  && defined(ASIO_HAS_STD_SYSTEM_ERROR) \+  && (_MSC_VER < 1800)+  // Microsoft's implementation of std::system_error is non-conformant in that+  // it ignores the error code's message when a "what" string is supplied. We'll+  // work around this by explicitly formatting the "what" string.+  std::string what_msg = location;+  what_msg += ": ";+  what_msg += err.message();+  asio::system_error e(err, what_msg);+  asio::detail::throw_exception(e ASIO_SOURCE_LOCATION_ARG);+#else // defined(ASIO_MSVC)+      //   && defined(ASIO_HAS_STD_SYSTEM_ERROR)+      //   && (_MSC_VER < 1928)+  // boostify: non-boost code ends here   asio::system_error e(err, location);   asio::detail::throw_exception(e ASIO_SOURCE_LOCATION_ARG);+  // boostify: non-boost code starts here+#endif // defined(ASIO_MSVC)+       //   && defined(ASIO_HAS_STD_SYSTEM_ERROR)+       //   && (_MSC_VER < 1800)+  // boostify: non-boost code ends here }  } // namespace detail
+ link/modules/asio-standalone/asio/include/asio/detail/impl/timer_queue_ptime.ipp view
@@ -0,0 +1,97 @@+//+// detail/impl/timer_queue_ptime.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP+#define ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(ASIO_HAS_BOOST_DATE_TIME)++#include "asio/detail/timer_queue_ptime.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++timer_queue<time_traits<boost::posix_time::ptime> >::timer_queue()+{+}++timer_queue<time_traits<boost::posix_time::ptime> >::~timer_queue()+{+}++bool timer_queue<time_traits<boost::posix_time::ptime> >::enqueue_timer(+    const time_type& time, per_timer_data& timer, wait_op* op)+{+  return impl_.enqueue_timer(time, timer, op);+}++bool timer_queue<time_traits<boost::posix_time::ptime> >::empty() const+{+  return impl_.empty();+}++long timer_queue<time_traits<boost::posix_time::ptime> >::wait_duration_msec(+    long max_duration) const+{+  return impl_.wait_duration_msec(max_duration);+}++long timer_queue<time_traits<boost::posix_time::ptime> >::wait_duration_usec(+    long max_duration) const+{+  return impl_.wait_duration_usec(max_duration);+}++void timer_queue<time_traits<boost::posix_time::ptime> >::get_ready_timers(+    op_queue<operation>& ops)+{+  impl_.get_ready_timers(ops);+}++void timer_queue<time_traits<boost::posix_time::ptime> >::get_all_timers(+    op_queue<operation>& ops)+{+  impl_.get_all_timers(ops);+}++std::size_t timer_queue<time_traits<boost::posix_time::ptime> >::cancel_timer(+    per_timer_data& timer, op_queue<operation>& ops, std::size_t max_cancelled)+{+  return impl_.cancel_timer(timer, ops, max_cancelled);+}++void timer_queue<time_traits<boost::posix_time::ptime> >::cancel_timer_by_key(+    per_timer_data* timer, op_queue<operation>& ops, void* cancellation_key)+{+  impl_.cancel_timer_by_key(timer, ops, cancellation_key);+}++void timer_queue<time_traits<boost::posix_time::ptime> >::move_timer(+    per_timer_data& target, per_timer_data& source)+{+  impl_.move_timer(target, source);+}++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_BOOST_DATE_TIME)++#endif // ASIO_DETAIL_IMPL_TIMER_QUEUE_PTIME_IPP
link/modules/asio-standalone/asio/include/asio/detail/impl/timer_queue_set.ipp view
@@ -2,7 +2,7 @@ // detail/impl/timer_queue_set.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_event.ipp view
@@ -2,7 +2,7 @@ // detail/win_event.ipp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_file_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_file_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -94,48 +94,25 @@   if ((open_flags & file_base::sync_all_on_write) != 0)     flags |= FILE_FLAG_WRITE_THROUGH; -  impl.offset_ = 0;   HANDLE handle = ::CreateFileA(path, access, share, 0, disposition, flags, 0);   if (handle != INVALID_HANDLE_VALUE)   {-    if (disposition == OPEN_ALWAYS)-    {-      if ((open_flags & file_base::truncate) != 0)-      {-        if (!::SetEndOfFile(handle))-        {-          DWORD last_error = ::GetLastError();-          ::CloseHandle(handle);-          ec.assign(last_error, asio::error::get_system_category());-          ASIO_ERROR_LOCATION(ec);-          return ec;-        }-      }-    }-    if (disposition == OPEN_ALWAYS || disposition == OPEN_EXISTING)+    if (disposition == OPEN_ALWAYS && (open_flags & file_base::truncate) != 0)     {-      if ((open_flags & file_base::append) != 0)+      if (!::SetEndOfFile(handle))       {-        LARGE_INTEGER distance, new_offset;-        distance.QuadPart = 0;-        if (::SetFilePointerEx(handle, distance, &new_offset, FILE_END))-        {-          impl.offset_ = static_cast<uint64_t>(new_offset.QuadPart);-        }-        else-        {-          DWORD last_error = ::GetLastError();-          ::CloseHandle(handle);-          ec.assign(last_error, asio::error::get_system_category());-          ASIO_ERROR_LOCATION(ec);-          return ec;-        }+        DWORD last_error = ::GetLastError();+        ::CloseHandle(handle);+        ec.assign(last_error, asio::error::get_system_category());+        ASIO_ERROR_LOCATION(ec);+        return ec;       }     }      handle_service_.assign(impl, handle, ec);     if (ec)       ::CloseHandle(handle);+    impl.offset_ = 0;     ASIO_ERROR_LOCATION(ec);     return ec;   }
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_handle_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_handle_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -163,7 +163,7 @@     win_iocp_handle_service::implementation_type& impl) {   close_for_destruction(impl);-+     // Remove implementation from linked list of all implementations.   asio::detail::mutex::scoped_lock lock(mutex_);   if (impl_list_ == &impl)@@ -365,12 +365,12 @@     return 0;   } -  // Write the data.+  // Write the data.    overlapped.Offset = offset & 0xFFFFFFFF;   overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;   BOOL ok = ::WriteFile(impl.handle_, buffer.data(),       static_cast<DWORD>(buffer.size()), 0, &overlapped);-  if (!ok)+  if (!ok)    {     DWORD last_error = ::GetLastError();     if (last_error != ERROR_IO_PENDING)@@ -446,7 +446,7 @@     ASIO_ERROR_LOCATION(ec);     return 0;   }-+     // A request to read 0 bytes on a stream handle is a no-op.   if (buffer.size() == 0)   {@@ -466,7 +466,7 @@   overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;   BOOL ok = ::ReadFile(impl.handle_, buffer.data(),       static_cast<DWORD>(buffer.size()), 0, &overlapped);-  if (!ok)+  if (!ok)    {     DWORD last_error = ::GetLastError();     if (last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_io_context.hpp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_io_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/completion_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp"  #include "asio/detail/push_options.hpp"@@ -29,26 +30,24 @@ namespace asio { namespace detail { -template <typename TimeTraits, typename Allocator>+template <typename Time_Traits> void win_iocp_io_context::add_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+    timer_queue<Time_Traits>& queue) {   do_add_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>+template <typename Time_Traits> void win_iocp_io_context::remove_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+    timer_queue<Time_Traits>& queue) {   do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void win_iocp_io_context::schedule_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    const typename TimeTraits::time_type& time,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-    wait_op* op)+template <typename Time_Traits>+void win_iocp_io_context::schedule_timer(timer_queue<Time_Traits>& queue,+    const typename Time_Traits::time_type& time,+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) {   // If the service has been shut down we silently discard the timer.   if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)@@ -65,10 +64,9 @@     update_timeout(); } -template <typename TimeTraits, typename Allocator>-std::size_t win_iocp_io_context::cancel_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t win_iocp_io_context::cancel_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& timer,     std::size_t max_cancelled) {   // If the service has been shut down we silently ignore the cancellation.@@ -83,10 +81,9 @@   return n; } -template <typename TimeTraits, typename Allocator>-void win_iocp_io_context::cancel_timer_by_key(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+template <typename Time_Traits>+void win_iocp_io_context::cancel_timer_by_key(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data* timer,     void* cancellation_key) {   // If the service has been shut down we silently ignore the cancellation.@@ -100,10 +97,10 @@   post_deferred_completions(ops); } -template <typename TimeTraits, typename Allocator>-void win_iocp_io_context::move_timer(timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& to,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& from)+template <typename Time_Traits>+void win_iocp_io_context::move_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& to,+    typename timer_queue<Time_Traits>::per_timer_data& from) {   asio::detail::mutex::scoped_lock lock(dispatch_mutex_);   op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_io_context.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_io_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,10 +19,10 @@  #if defined(ASIO_HAS_IOCP) -#include "asio/config.hpp" #include "asio/error.hpp" #include "asio/detail/cstdint.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/limits.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/throw_error.hpp"@@ -51,7 +51,7 @@  struct win_iocp_io_context::work_finished_on_block_exit {-  ~work_finished_on_block_exit() noexcept(false)+  ~work_finished_on_block_exit() ASIO_NOEXCEPT_IF(false)   {     io_context_->work_finished();   }@@ -79,7 +79,7 @@ };  win_iocp_io_context::win_iocp_io_context(-    asio::execution_context& ctx, bool own_thread)+    asio::execution_context& ctx, int concurrency_hint, bool own_thread)   : execution_context_service_base<win_iocp_io_context>(ctx),     iocp_(),     outstanding_work_(0),@@ -88,13 +88,12 @@     shutdown_(0),     gqcs_timeout_(get_gqcs_timeout()),     dispatch_required_(0),-    concurrency_hint_(config(ctx).get("scheduler", "concurrency_hint", -1))+    concurrency_hint_(concurrency_hint) {   ASIO_HANDLER_TRACKING_INIT;    iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,-      static_cast<DWORD>(concurrency_hint_ >= 0-        ? concurrency_hint_ : DWORD(~0)));+      static_cast<DWORD>(concurrency_hint >= 0 ? concurrency_hint : DWORD(~0)));   if (!iocp_.handle)   {     DWORD last_error = ::GetLastError();@@ -106,42 +105,17 @@   if (own_thread)   {     ::InterlockedIncrement(&outstanding_work_);-    thread_ = thread(thread_function(this));-  }-}--win_iocp_io_context::win_iocp_io_context(-    win_iocp_io_context::internal, asio::execution_context& ctx)-  : execution_context_service_base<win_iocp_io_context>(ctx),-    iocp_(),-    outstanding_work_(0),-    stopped_(0),-    stop_event_posted_(0),-    shutdown_(0),-    gqcs_timeout_(get_gqcs_timeout()),-    dispatch_required_(0),-    concurrency_hint_(-1)-{-  ASIO_HANDLER_TRACKING_INIT;--  iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,-      static_cast<DWORD>(concurrency_hint_ >= 0-        ? concurrency_hint_ : DWORD(~0)));-  if (!iocp_.handle)-  {-    DWORD last_error = ::GetLastError();-    asio::error_code ec(last_error,-        asio::error::get_system_category());-    asio::detail::throw_error(ec, "iocp");+    thread_.reset(new asio::detail::thread(thread_function(this)));   } }  win_iocp_io_context::~win_iocp_io_context() {-  if (thread_.joinable())+  if (thread_.get())   {     stop();-    thread_.join();+    thread_->join();+    thread_.reset();   } } @@ -149,17 +123,18 @@ {   ::InterlockedExchange(&shutdown_, 1); -  if (timer_thread_.joinable())+  if (timer_thread_.get())   {     LARGE_INTEGER timeout;     timeout.QuadPart = 1;     ::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE);   } -  if (thread_.joinable())+  if (thread_.get())   {     stop();-    thread_.join();+    thread_->join();+    thread_.reset();     ::InterlockedDecrement(&outstanding_work_);   } @@ -192,7 +167,11 @@     }   } -  timer_thread_.join();+  if (timer_thread_.get())+  {+    timer_thread_->join();+    timer_thread_.reset();+  } }  asio::error_code win_iocp_io_context::register_handle(@@ -593,10 +572,10 @@         &timeout, max_timeout_msec, 0, 0, FALSE);   } -  if (!timer_thread_.joinable())+  if (!timer_thread_.get())   {     timer_thread_function thread_function = { this };-    timer_thread_ = thread(thread_function, 65536);+    timer_thread_.reset(new thread(thread_function, 65536));   } } @@ -609,7 +588,7 @@  void win_iocp_io_context::update_timeout() {-  if (timer_thread_.joinable())+  if (timer_thread_.get())   {     // There's no point updating the waitable timer if the new timeout period     // exceeds the maximum timeout. In that case, we might as well wait for the
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_serial_port_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_serial_port_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/impl/win_iocp_socket_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_iocp_socket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -72,7 +72,7 @@ void win_iocp_socket_service_base::base_move_construct(     win_iocp_socket_service_base::base_implementation_type& impl,     win_iocp_socket_service_base::base_implementation_type& other_impl)-  noexcept+  ASIO_NOEXCEPT {   impl.socket_ = other_impl.socket_;   other_impl.socket_ = invalid_socket;
link/modules/asio-standalone/asio/include/asio/detail/impl/win_mutex.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_mutex.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_object_handle_service.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_object_handle_service.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/impl/win_static_mutex.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_static_mutex.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/win_thread.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_thread.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -33,30 +33,26 @@  win_thread::~win_thread() {-  if (arg_)-    std::terminate();+  ::CloseHandle(thread_);++  // The exit_event_ handle is deliberately allowed to leak here since it+  // is an error for the owner of an internal thread not to join() it. }  void win_thread::join() {-  if (arg_)+  HANDLE handles[2] = { exit_event_, thread_ };+  ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);+  ::CloseHandle(exit_event_);+  if (terminate_threads())   {-    HANDLE handles[2] = { arg_->exit_event_, arg_->thread_ };-    ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);-    ::CloseHandle(arg_->exit_event_);-    if (terminate_threads())-    {-      ::TerminateThread(arg_->thread_, 0);-    }-    else-    {-      ::QueueUserAPC(apc_function, arg_->thread_, 0);-      ::WaitForSingleObject(arg_->thread_, INFINITE);-    }-    ::CloseHandle(arg_->thread_);-    arg_->destroy();-    arg_ = 0;+    ::TerminateThread(thread_, 0);   }+  else+  {+    ::QueueUserAPC(apc_function, thread_, 0);+    ::WaitForSingleObject(thread_, INFINITE);+  } }  std::size_t win_thread::hardware_concurrency()@@ -66,68 +62,71 @@   return system_info.dwNumberOfProcessors; } -win_thread::func_base* win_thread::start_thread(-    func_base* arg, unsigned int stack_size)+void win_thread::start_thread(func_base* arg, unsigned int stack_size) {-  arg->entry_event_ = ::CreateEventW(0, true, false, 0);-  if (!arg->entry_event_)+  ::HANDLE entry_event = 0;+  arg->entry_event_ = entry_event = ::CreateEventW(0, true, false, 0);+  if (!entry_event)   {     DWORD last_error = ::GetLastError();-    arg->destroy();+    delete arg;     asio::error_code ec(last_error,         asio::error::get_system_category());     asio::detail::throw_error(ec, "thread.entry_event");   } -  arg->exit_event_ = ::CreateEventW(0, true, false, 0);-  if (!arg->exit_event_)+  arg->exit_event_ = exit_event_ = ::CreateEventW(0, true, false, 0);+  if (!exit_event_)   {     DWORD last_error = ::GetLastError();-    ::CloseHandle(arg->entry_event_);-    arg->destroy();+    delete arg;     asio::error_code ec(last_error,         asio::error::get_system_category());     asio::detail::throw_error(ec, "thread.exit_event");   }    unsigned int thread_id = 0;-  arg->thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0,+  thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0,         stack_size, win_thread_function, arg, 0, &thread_id));-  if (!arg->thread_)+  if (!thread_)   {     DWORD last_error = ::GetLastError();-    ::CloseHandle(arg->entry_event_);-    ::CloseHandle(arg->exit_event_);-    arg->destroy();+    delete arg;+    if (entry_event)+      ::CloseHandle(entry_event);+    if (exit_event_)+      ::CloseHandle(exit_event_);     asio::error_code ec(last_error,         asio::error::get_system_category());     asio::detail::throw_error(ec, "thread");   } -  if (arg->entry_event_)+  if (entry_event)   {-    ::WaitForSingleObject(arg->entry_event_, INFINITE);-    ::CloseHandle(arg->entry_event_);-    arg->entry_event_ = 0;+    ::WaitForSingleObject(entry_event, INFINITE);+    ::CloseHandle(entry_event);   }--  return arg; }  unsigned int __stdcall win_thread_function(void* arg) {-  win_thread::func_base* func = static_cast<win_thread::func_base*>(arg);-  ::SetEvent(func->entry_event_);+  win_thread::auto_func_base_ptr func = {+      static_cast<win_thread::func_base*>(arg) }; -  func->run();+  ::SetEvent(func.ptr->entry_event_); +  func.ptr->run();+   // Signal that the thread has finished its work, but rather than returning go   // to sleep to put the thread into a well known state. If the thread is being   // joined during global object destruction then it may be killed using   // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx   // call will be interrupted using QueueUserAPC and the thread will shut down   // cleanly.-  ::SetEvent(func->exit_event_);+  HANDLE exit_event = func.ptr->exit_event_;+  delete func.ptr;+  func.ptr = 0;+  ::SetEvent(exit_event);   ::SleepEx(INFINITE, TRUE);    return 0;
link/modules/asio-standalone/asio/include/asio/detail/impl/win_tss_ptr.ipp view
@@ -2,7 +2,7 @@ // detail/impl/win_tss_ptr.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_ssocket_service_base.ipp view
@@ -2,7 +2,7 @@ // detail/impl/winrt_ssocket_service_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -66,7 +66,7 @@ void winrt_ssocket_service_base::base_move_construct(     winrt_ssocket_service_base::base_implementation_type& impl,     winrt_ssocket_service_base::base_implementation_type& other_impl)-  noexcept+  ASIO_NOEXCEPT {   impl.socket_ = other_impl.socket_;   other_impl.socket_ = nullptr;
link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_timer_scheduler.hpp view
@@ -2,7 +2,7 @@ // detail/impl/winrt_timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -24,27 +24,23 @@ namespace asio { namespace detail { -template <typename TimeTraits, typename Allocator>-void winrt_timer_scheduler::add_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void winrt_timer_scheduler::add_timer_queue(timer_queue<Time_Traits>& queue) {   do_add_timer_queue(queue); }  // Remove a timer queue from the reactor.-template <typename TimeTraits, typename Allocator>-void winrt_timer_scheduler::remove_timer_queue(-    timer_queue<TimeTraits, Allocator>& queue)+template <typename Time_Traits>+void winrt_timer_scheduler::remove_timer_queue(timer_queue<Time_Traits>& queue) {   do_remove_timer_queue(queue); } -template <typename TimeTraits, typename Allocator>-void winrt_timer_scheduler::schedule_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    const typename TimeTraits::time_type& time,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-    wait_op* op)+template <typename Time_Traits>+void winrt_timer_scheduler::schedule_timer(timer_queue<Time_Traits>& queue,+    const typename Time_Traits::time_type& time,+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op) {   asio::detail::mutex::scoped_lock lock(mutex_); @@ -60,10 +56,9 @@     event_.signal(lock); } -template <typename TimeTraits, typename Allocator>-std::size_t winrt_timer_scheduler::cancel_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+template <typename Time_Traits>+std::size_t winrt_timer_scheduler::cancel_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& timer,     std::size_t max_cancelled) {   asio::detail::mutex::scoped_lock lock(mutex_);@@ -74,11 +69,10 @@   return n; } -template <typename TimeTraits, typename Allocator>-void winrt_timer_scheduler::move_timer(-    timer_queue<TimeTraits, Allocator>& queue,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& to,-    typename timer_queue<TimeTraits, Allocator>::per_timer_data& from)+template <typename Time_Traits>+void winrt_timer_scheduler::move_timer(timer_queue<Time_Traits>& queue,+    typename timer_queue<Time_Traits>::per_timer_data& to,+    typename timer_queue<Time_Traits>::per_timer_data& from) {   asio::detail::mutex::scoped_lock lock(mutex_);   op_queue<operation> ops;
link/modules/asio-standalone/asio/include/asio/detail/impl/winrt_timer_scheduler.ipp view
@@ -2,7 +2,7 @@ // detail/impl/winrt_timer_scheduler.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -33,11 +33,12 @@     mutex_(),     event_(),     timer_queues_(),-    thread_(),+    thread_(0),     stop_thread_(false),     shutdown_(false) {-  thread_ = thread(bind_handler(&winrt_timer_scheduler::call_run_thread, this));+  thread_ = new asio::detail::thread(+      bind_handler(&winrt_timer_scheduler::call_run_thread, this)); }  winrt_timer_scheduler::~winrt_timer_scheduler()@@ -52,7 +53,13 @@   stop_thread_ = true;   event_.signal(lock);   lock.unlock();-  thread_.join();++  if (thread_)+  {+    thread_->join();+    delete thread_;+    thread_ = 0;+  }    op_queue<operation> ops;   timer_queues_.get_all_timers(ops);
link/modules/asio-standalone/asio/include/asio/detail/impl/winsock_init.ipp view
@@ -2,7 +2,7 @@ // detail/impl/winsock_init.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/initiate_defer.hpp view
@@ -2,7 +2,7 @@ // detail/initiate_defer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -34,44 +34,62 @@ { public:   template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         execution::is_executor<-          associated_executor_t<decay_t<CompletionHandler>>+          typename associated_executor<+            typename decay<CompletionHandler>::type+          >::type         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_executor_t<decay_t<CompletionHandler>> ex(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_executor<handler_t>::type ex(         (get_associated_executor)(handler)); -    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(         asio::require(ex, execution::blocking.never),         execution::relationship.continuation,         execution::allocator(alloc)       ).execute(         asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)));+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(+          asio::require(ex, execution::blocking.never),+          execution::relationship.continuation,+          execution::allocator(alloc)),+        asio::detail::bind_handler(+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED)   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         !execution::is_executor<-          associated_executor_t<decay_t<CompletionHandler>>+          typename associated_executor<+            typename decay<CompletionHandler>::type+          >::type         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_executor_t<decay_t<CompletionHandler>> ex(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_executor<handler_t>::type ex(         (get_associated_executor)(handler)); -    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler));      ex.defer(asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)), alloc);+          ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);   } }; @@ -86,113 +104,140 @@   {   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return ex_;   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(         asio::require(ex_, execution::blocking.never),         execution::relationship.continuation,         execution::allocator(alloc)       ).execute(         asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)));+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(+          asio::require(ex_, execution::blocking.never),+          execution::relationship.continuation,+          execution::allocator(alloc)),+        asio::detail::bind_handler(+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED)   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    typedef decay_t<CompletionHandler> handler_t;+    typedef typename decay<CompletionHandler>::type handler_t; -    typedef associated_executor_t<handler_t, Executor> handler_ex_t;+    typedef typename associated_executor<+      handler_t, Executor>::type handler_ex_t;     handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); -    associated_allocator_t<handler_t> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(         asio::require(ex_, execution::blocking.never),         execution::relationship.continuation,         execution::allocator(alloc)       ).execute(         detail::work_dispatcher<handler_t, handler_ex_t>(-          static_cast<CompletionHandler&&>(handler), handler_ex));+          ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(+          asio::require(ex_, execution::blocking.never),+          execution::relationship.continuation,+          execution::allocator(alloc)),+        detail::work_dispatcher<handler_t, handler_ex_t>(+          ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#endif // defined(ASIO_NO_DEPRECATED)   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         !execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler));      ex_.defer(asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)), alloc);+          ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         !execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    typedef decay_t<CompletionHandler> handler_t;+    typedef typename decay<CompletionHandler>::type handler_t; -    typedef associated_executor_t<handler_t, Executor> handler_ex_t;+    typedef typename associated_executor<+      handler_t, Executor>::type handler_ex_t;     handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); -    associated_allocator_t<handler_t> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler));      ex_.defer(detail::work_dispatcher<handler_t, handler_ex_t>(-          static_cast<CompletionHandler&&>(handler), handler_ex), alloc);+          ASIO_MOVE_CAST(CompletionHandler)(handler),+          handler_ex), alloc);   }  private:
link/modules/asio-standalone/asio/include/asio/detail/initiate_dispatch.hpp view
@@ -2,7 +2,7 @@ // detail/initiate_dispatch.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -32,40 +32,55 @@ { public:   template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         execution::is_executor<-          associated_executor_t<decay_t<CompletionHandler>>+          typename associated_executor<+            typename decay<CompletionHandler>::type+          >::type         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_executor_t<decay_t<CompletionHandler>> ex(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_executor<handler_t>::type ex(         (get_associated_executor)(handler)); -    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(ex, execution::allocator(alloc)).execute(         asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)));+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(ex, execution::allocator(alloc)),+        asio::detail::bind_handler(+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED)   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         !execution::is_executor<-          associated_executor_t<decay_t<CompletionHandler>>+          typename associated_executor<+            typename decay<CompletionHandler>::type+          >::type         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_executor_t<decay_t<CompletionHandler>> ex(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_executor<handler_t>::type ex(         (get_associated_executor)(handler)); -    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler));      ex.dispatch(asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)), alloc);+          ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);   } }; @@ -80,105 +95,126 @@   {   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return ex_;   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(ex_, execution::allocator(alloc)).execute(         asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)));+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(ex_, execution::allocator(alloc)),+        asio::detail::bind_handler(+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED)   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    typedef decay_t<CompletionHandler> handler_t;+    typedef typename decay<CompletionHandler>::type handler_t; -    typedef associated_executor_t<handler_t, Executor> handler_ex_t;+    typedef typename associated_executor<+      handler_t, Executor>::type handler_ex_t;     handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); -    associated_allocator_t<handler_t> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(ex_, execution::allocator(alloc)).execute(         detail::work_dispatcher<handler_t, handler_ex_t>(-          static_cast<CompletionHandler&&>(handler), handler_ex));+          ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(ex_, execution::allocator(alloc)),+        detail::work_dispatcher<handler_t, handler_ex_t>(+          ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#endif // defined(ASIO_NO_DEPRECATED)   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         !execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler));      ex_.dispatch(asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)), alloc);+          ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         !execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    typedef decay_t<CompletionHandler> handler_t;+    typedef typename decay<CompletionHandler>::type handler_t; -    typedef associated_executor_t<handler_t, Executor> handler_ex_t;+    typedef typename associated_executor<+      handler_t, Executor>::type handler_ex_t;     handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); -    associated_allocator_t<handler_t> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler));      ex_.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>(-          static_cast<CompletionHandler&&>(handler), handler_ex), alloc);+          ASIO_MOVE_CAST(CompletionHandler)(handler),+          handler_ex), alloc);   }  private:
link/modules/asio-standalone/asio/include/asio/detail/initiate_post.hpp view
@@ -2,7 +2,7 @@ // detail/initiate_post.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -34,44 +34,62 @@ { public:   template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         execution::is_executor<-          associated_executor_t<decay_t<CompletionHandler>>+          typename associated_executor<+            typename decay<CompletionHandler>::type+          >::type         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_executor_t<decay_t<CompletionHandler>> ex(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_executor<handler_t>::type ex(         (get_associated_executor)(handler)); -    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(         asio::require(ex, execution::blocking.never),         execution::relationship.fork,         execution::allocator(alloc)       ).execute(         asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)));+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(+          asio::require(ex, execution::blocking.never),+          execution::relationship.fork,+          execution::allocator(alloc)),+        asio::detail::bind_handler(+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED)   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         !execution::is_executor<-          associated_executor_t<decay_t<CompletionHandler>>+          typename associated_executor<+            typename decay<CompletionHandler>::type+          >::type         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_executor_t<decay_t<CompletionHandler>> ex(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_executor<handler_t>::type ex(         (get_associated_executor)(handler)); -    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler));      ex.post(asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)), alloc);+          ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);   } }; @@ -86,113 +104,140 @@   {   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return ex_;   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(         asio::require(ex_, execution::blocking.never),         execution::relationship.fork,         execution::allocator(alloc)       ).execute(         asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)));+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(+          asio::require(ex_, execution::blocking.never),+          execution::relationship.fork,+          execution::allocator(alloc)),+        asio::detail::bind_handler(+          ASIO_MOVE_CAST(CompletionHandler)(handler)));+#endif // defined(ASIO_NO_DEPRECATED)   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    typedef decay_t<CompletionHandler> handler_t;+    typedef typename decay<CompletionHandler>::type handler_t; -    typedef associated_executor_t<handler_t, Executor> handler_ex_t;+    typedef typename associated_executor<+      handler_t, Executor>::type handler_ex_t;     handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); -    associated_allocator_t<handler_t> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler)); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(         asio::require(ex_, execution::blocking.never),         execution::relationship.fork,         execution::allocator(alloc)       ).execute(         detail::work_dispatcher<handler_t, handler_ex_t>(-          static_cast<CompletionHandler&&>(handler), handler_ex));+          ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(+          asio::require(ex_, execution::blocking.never),+          execution::relationship.fork,+          execution::allocator(alloc)),+        detail::work_dispatcher<handler_t, handler_ex_t>(+          ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));+#endif // defined(ASIO_NO_DEPRECATED)   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         !execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    associated_allocator_t<decay_t<CompletionHandler>> alloc(+    typedef typename decay<CompletionHandler>::type handler_t;++    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler));      ex_.post(asio::detail::bind_handler(-          static_cast<CompletionHandler&&>(handler)), alloc);+          ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);   }    template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler,-      enable_if_t<+  void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,+      typename enable_if<         !execution::is_executor<-          conditional_t<true, executor_type, CompletionHandler>+          typename conditional<true, executor_type, CompletionHandler>::type         >::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         detail::is_work_dispatcher_required<-          decay_t<CompletionHandler>,+          typename decay<CompletionHandler>::type,           Executor         >::value-      >* = 0) const+      >::type* = 0) const   {-    typedef decay_t<CompletionHandler> handler_t;+    typedef typename decay<CompletionHandler>::type handler_t; -    typedef associated_executor_t<handler_t, Executor> handler_ex_t;+    typedef typename associated_executor<+      handler_t, Executor>::type handler_ex_t;     handler_ex_t handler_ex((get_associated_executor)(handler, ex_)); -    associated_allocator_t<handler_t> alloc(+    typename associated_allocator<handler_t>::type alloc(         (get_associated_allocator)(handler));      ex_.post(detail::work_dispatcher<handler_t, handler_ex_t>(-          static_cast<CompletionHandler&&>(handler), handler_ex), alloc);+          ASIO_MOVE_CAST(CompletionHandler)(handler),+          handler_ex), alloc);   }  private:
− link/modules/asio-standalone/asio/include/asio/detail/initiation_base.hpp
@@ -1,62 +0,0 @@-//-// detail/initiation_base.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DETAIL_INITIATION_BASE_HPP-#define ASIO_DETAIL_INITIATION_BASE_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Initiation, typename = void>-class initiation_base : public Initiation-{-public:-  template <typename I>-  explicit initiation_base(I&& initiation)-    : Initiation(static_cast<I&&>(initiation))-  {-  }-};--template <typename Initiation>-class initiation_base<Initiation, enable_if_t<!is_class<Initiation>::value>>-{-public:-  template <typename I>-  explicit initiation_base(I&& initiation)-    : initiation_(static_cast<I&&>(initiation))-  {-  }--  template <typename... Args>-  void operator()(Args&&... args) const-  {-    initiation_(static_cast<Args&&>(args)...);-  }--private:-  Initiation initiation_;-};--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_INITIATION_BASE_HPP
link/modules/asio-standalone/asio/include/asio/detail/io_control.hpp view
@@ -2,7 +2,7 @@ // detail/io_control.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/io_object_impl.hpp view
@@ -1,8 +1,8 @@ //-// detail/io_object_impl.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~+// io_object_impl.hpp+// ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -60,6 +60,7 @@     service_->construct(implementation_);   } +#if defined(ASIO_HAS_MOVE)   // Move-construct an I/O object.   io_object_impl(io_object_impl&& other)     : service_(&other.get_service()),@@ -87,6 +88,7 @@     service_->converting_move_construct(implementation_,         other.get_service(), other.get_implementation());   }+#endif // defined(ASIO_HAS_MOVE)    // Destructor.   ~io_object_impl()@@ -94,6 +96,7 @@     service_->destroy(implementation_);   } +#if defined(ASIO_HAS_MOVE)   // Move-assign an I/O object.   io_object_impl& operator=(io_object_impl&& other)   {@@ -107,9 +110,10 @@     }     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    // Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return executor_;   }@@ -142,7 +146,7 @@   // Helper function to get an executor's context.   template <typename T>   static execution_context& get_context(const T& t,-      enable_if_t<execution::is_executor<T>::value>* = 0)+      typename enable_if<execution::is_executor<T>::value>::type* = 0)   {     return asio::query(t, execution::context);   }@@ -150,7 +154,7 @@   // Helper function to get an executor's context.   template <typename T>   static execution_context& get_context(const T& t,-      enable_if_t<!execution::is_executor<T>::value>* = 0)+      typename enable_if<!execution::is_executor<T>::value>::type* = 0)   {     return t.context();   }
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_read_at_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_read_at_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -135,7 +135,7 @@     : io_uring_descriptor_read_at_op_base<MutableBufferSequence>(         success_ec, descriptor, state, offset, buffers,         &io_uring_descriptor_read_at_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -154,7 +154,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_read_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -63,7 +63,7 @@     {       ::io_uring_prep_read_fixed(sqe, o->descriptor_,           o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,-          -1, o->bufs_.registered_id().native_handle());+          0, o->bufs_.registered_id().native_handle());     }     else     {@@ -130,7 +130,7 @@       Handler& handler, const IoExecutor& io_ex)     : io_uring_descriptor_read_op_base<MutableBufferSequence>(success_ec,         descriptor, state, buffers, &io_uring_descriptor_read_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -149,7 +149,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_service.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -85,7 +85,7 @@    // Move-construct a new descriptor implementation.   ASIO_DECL void move_construct(implementation_type& impl,-      implementation_type& other_impl) noexcept;+      implementation_type& other_impl) ASIO_NOEXCEPT;    // Move-assign from another descriptor implementation.   ASIO_DECL void move_assign(implementation_type& impl,@@ -209,7 +209,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      int op_type;@@ -304,7 +304,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -340,7 +340,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -409,7 +409,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -494,7 +494,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -530,7 +530,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -596,7 +596,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_write_at_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_write_at_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -129,7 +129,7 @@     : io_uring_descriptor_write_at_op_base<ConstBufferSequence>(         success_ec, descriptor, state, offset, buffers,         &io_uring_descriptor_write_at_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -148,7 +148,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_descriptor_write_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_descriptor_write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -63,7 +63,7 @@     {       ::io_uring_prep_write_fixed(sqe, o->descriptor_,           o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,-          -1, o->bufs_.registered_id().native_handle());+          0, o->bufs_.registered_id().native_handle());     }     else     {@@ -125,7 +125,7 @@       const IoExecutor& io_ex)     : io_uring_descriptor_write_op_base<ConstBufferSequence>(success_ec,         descriptor, state, buffers, &io_uring_descriptor_write_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -144,7 +144,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_file_service.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_file_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/io_uring_null_buffers_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_null_buffers_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/io_uring_operation.hpp" #include "asio/detail/memory.hpp"@@ -40,7 +41,7 @@         &io_uring_null_buffers_op::do_prepare,         &io_uring_null_buffers_op::do_perform,         &io_uring_null_buffers_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex),       descriptor_(descriptor),       poll_flags_(poll_flags)@@ -73,7 +74,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_operation.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/io_uring_service.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -69,8 +69,11 @@   };    // Per I/O object state.-  struct io_object+  class io_object   {+    friend class io_uring_service;+    friend class object_pool_access;+     io_object* next_;     io_object* prev_; @@ -79,7 +82,7 @@     io_queue queues_[max_ops];     bool shutdown_; -    ASIO_DECL io_object(bool locking, int spin_count);+    ASIO_DECL io_object(bool locking);   };    // Per I/O object data.@@ -143,39 +146,38 @@   ASIO_DECL void cleanup_io_object(per_io_object_data& io_obj);    // Add a new timer queue to the reactor.-  template <typename TimeTraits, typename Allocator>-  void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+  template <typename Time_Traits>+  void add_timer_queue(timer_queue<Time_Traits>& timer_queue);    // Remove a timer queue from the reactor.-  template <typename TimeTraits, typename Allocator>-  void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+  template <typename Time_Traits>+  void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);    // Schedule a new operation in the given timer queue to expire at the   // specified absolute time.-  template <typename TimeTraits, typename Allocator>-  void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,-      const typename TimeTraits::time_type& time,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-      wait_op* op);+  template <typename Time_Traits>+  void schedule_timer(timer_queue<Time_Traits>& queue,+      const typename Time_Traits::time_type& time,+      typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);    // Cancel the timer operations associated with the given token. Returns the   // number of operations that have been posted or dispatched.-  template <typename TimeTraits, typename Allocator>-  std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+  template <typename Time_Traits>+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& timer,       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());    // Cancel the timer operations associated with the given key.-  template <typename TimeTraits, typename Allocator>-  void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+  template <typename Time_Traits>+  void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data* timer,       void* cancellation_key);    // Move the timer operations associated with the given timer.-  template <typename TimeTraits, typename Allocator>-  void move_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+  template <typename Time_Traits>+  void move_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& target,+      typename timer_queue<Time_Traits>::per_timer_data& source);    // Wait on io_uring once until interrupted or events are ready to be   // dispatched.@@ -275,12 +277,6 @@   // Whether the service has been shut down.   bool shutdown_; -  // Whether I/O locking is enabled.-  const bool io_locking_;--  // How any times to spin waiting for the I/O mutex.-  const int io_locking_spin_count_;-   // The timer queues.   timer_queue_set timer_queues_; @@ -292,8 +288,7 @@   mutex registration_mutex_;    // Keep track of all registered I/O objects.-  object_pool<io_object, execution_context::allocator<void>>-    registered_io_objects_;+  object_pool<io_object> registered_io_objects_;    // Helper class to do post-perform_io cleanup.   struct perform_io_cleanup_on_block_exit;
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_accept_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_accept_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/io_uring_operation.hpp" #include "asio/detail/memory.hpp"@@ -138,7 +139,7 @@     : io_uring_socket_accept_op_base<Socket, Protocol>(         success_ec, socket, state, peer, protocol, peer_endpoint,         &io_uring_socket_accept_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -160,7 +161,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -191,6 +192,8 @@   handler_work<Handler, IoExecutor> work_; }; +#if defined(ASIO_HAS_MOVE)+ template <typename Protocol, typename PeerIoExecutor,     typename Handler, typename IoExecutor> class io_uring_socket_move_accept_op :@@ -211,7 +214,7 @@       io_uring_socket_accept_op_base<peer_socket_type, Protocol>(         success_ec, socket, state, *this, protocol, peer_endpoint,         &io_uring_socket_move_accept_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -234,7 +237,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -247,8 +250,8 @@     // deallocated the memory here.     detail::move_binder2<Handler,       asio::error_code, peer_socket_type>-        handler(0, static_cast<Handler&&>(o->handler_), o->ec_,-          static_cast<peer_socket_type&&>(*o));+        handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,+          ASIO_MOVE_CAST(peer_socket_type)(*o));     p.h = asio::detail::addressof(handler.handler_);     p.reset(); @@ -269,6 +272,8 @@   Handler handler_;   handler_work<Handler, IoExecutor> work_; };++#endif // defined(ASIO_HAS_MOVE)  } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_connect_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/io_uring_operation.hpp" #include "asio/detail/memory.hpp"@@ -80,7 +81,7 @@       Handler& handler, const IoExecutor& io_ex)     : io_uring_socket_connect_op_base<Protocol>(success_ec, socket,         endpoint, &io_uring_socket_connect_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -99,7 +100,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_recv_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -70,7 +70,7 @@     {       ::io_uring_prep_read_fixed(sqe, o->socket_,           o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,-          -1, o->bufs_.registered_id().native_handle());+          0, o->bufs_.registered_id().native_handle());     }     else     {@@ -145,7 +145,7 @@       Handler& handler, const IoExecutor& io_ex)     : io_uring_socket_recv_op_base<MutableBufferSequence>(success_ec,         socket, state, buffers, flags, &io_uring_socket_recv_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -164,7 +164,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_recvfrom_op.hpp view
@@ -1,8 +1,8 @@ // // detail/io_uring_socket_recvfrom_op.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -146,7 +146,7 @@     : io_uring_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>(         success_ec, socket, state, buffers, endpoint, flags,         &io_uring_socket_recvfrom_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -165,7 +165,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_recvmsg_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_recvmsg_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -132,7 +132,7 @@     : io_uring_socket_recvmsg_op_base<MutableBufferSequence>(success_ec,         socket, state, buffers, in_flags, out_flags,         &io_uring_socket_recvmsg_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -151,7 +151,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_send_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -69,7 +69,7 @@     {       ::io_uring_prep_write_fixed(sqe, o->socket_,           o->bufs_.buffers()->iov_base, o->bufs_.buffers()->iov_len,-          -1, o->bufs_.registered_id().native_handle());+          0, o->bufs_.registered_id().native_handle());     }     else     {@@ -131,7 +131,7 @@       Handler& handler, const IoExecutor& io_ex)     : io_uring_socket_send_op_base<ConstBufferSequence>(success_ec,         socket, state, buffers, flags, &io_uring_socket_send_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -150,7 +150,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_sendto_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_sendto_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -134,7 +134,7 @@     : io_uring_socket_sendto_op_base<ConstBufferSequence, Endpoint>(         success_ec, socket, state, buffers, endpoint, flags,         &io_uring_socket_sendto_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -153,7 +153,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_service.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -44,7 +44,7 @@  template <typename Protocol> class io_uring_socket_service :-  public execution_context_service_base<io_uring_socket_service<Protocol>>,+  public execution_context_service_base<io_uring_socket_service<Protocol> >,   public io_uring_socket_service_base { public:@@ -74,7 +74,7 @@   // Constructor.   io_uring_socket_service(execution_context& context)     : execution_context_service_base<-        io_uring_socket_service<Protocol>>(context),+        io_uring_socket_service<Protocol> >(context),       io_uring_socket_service_base(context)   {   }@@ -87,7 +87,7 @@    // Move-construct a new socket implementation.   void move_construct(implementation_type& impl,-      implementation_type& other_impl) noexcept+      implementation_type& other_impl) ASIO_NOEXCEPT   {     this->base_move_construct(impl, other_impl); @@ -275,7 +275,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -310,7 +310,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -398,7 +398,7 @@     int op_type = (flags & socket_base::message_out_of_band)       ? io_uring_service::except_op : io_uring_service::read_op; -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -446,7 +446,7 @@       poll_flags = POLLIN;     } -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -514,7 +514,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -539,6 +539,7 @@     p.v = p.p = 0;   } +#if defined(ASIO_HAS_MOVE)   // Start an asynchronous accept. The peer_endpoint object must be valid until   // the accept's handler is invoked.   template <typename PeerIoExecutor, typename Handler, typename IoExecutor>@@ -549,7 +550,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -574,6 +575,7 @@     start_accept_op(impl, p.p, is_continuation, false);     p.v = p.p = 0;   }+#endif // defined(ASIO_HAS_MOVE)    // Connect the socket to the specified endpoint.   asio::error_code connect(implementation_type& impl,@@ -593,7 +595,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/io_uring_socket_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_socket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -72,7 +72,7 @@    // Move-construct a new socket implementation.   ASIO_DECL void base_move_construct(base_implementation_type& impl,-      base_implementation_type& other_impl) noexcept;+      base_implementation_type& other_impl) ASIO_NOEXCEPT;    // Move-assign from another socket implementation.   ASIO_DECL void base_move_assign(base_implementation_type& impl,@@ -199,7 +199,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      int op_type;@@ -289,7 +289,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -326,7 +326,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -397,7 +397,7 @@     int op_type = (flags & socket_base::message_out_of_band)       ? io_uring_service::except_op : io_uring_service::read_op; -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -448,7 +448,7 @@       poll_flags = POLLIN;     } -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -517,7 +517,7 @@     int op_type = (in_flags & socket_base::message_out_of_band)       ? io_uring_service::except_op : io_uring_service::read_op; -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -566,7 +566,7 @@       poll_flags = POLLIN;     } -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/io_uring_wait_op.hpp view
@@ -2,7 +2,7 @@ // detail/io_uring_wait_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/io_uring_operation.hpp" #include "asio/detail/memory.hpp"@@ -38,7 +39,7 @@       int poll_flags, Handler& handler, const IoExecutor& io_ex)     : io_uring_operation(success_ec, &io_uring_wait_op::do_prepare,         &io_uring_wait_op::do_perform, &io_uring_wait_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex),       descriptor_(descriptor),       poll_flags_(poll_flags)@@ -71,7 +72,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/is_buffer_sequence.hpp view
@@ -2,7 +2,7 @@ // detail/is_buffer_sequence.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -55,25 +55,55 @@ { }; +#if defined(ASIO_HAS_DECLTYPE)+ template <typename> char buffer_sequence_begin_helper(...);  template <typename T> char (&buffer_sequence_begin_helper(T* t,-    enable_if_t<!is_same<+    typename enable_if<!is_same<       decltype(asio::buffer_sequence_begin(*t)),-        void>::value>*))[2];+        void>::value>::type*))[2]; +#else // defined(ASIO_HAS_DECLTYPE)+ template <typename>+char (&buffer_sequence_begin_helper(...))[2];++template <typename T>+char buffer_sequence_begin_helper(T* t,+    buffer_sequence_memfns_check<+      void (buffer_sequence_memfns_base::*)(),+      &buffer_sequence_memfns_derived<T>::begin>*);++#endif // defined(ASIO_HAS_DECLTYPE)++#if defined(ASIO_HAS_DECLTYPE)++template <typename> char buffer_sequence_end_helper(...);  template <typename T> char (&buffer_sequence_end_helper(T* t,-    enable_if_t<!is_same<+    typename enable_if<!is_same<       decltype(asio::buffer_sequence_end(*t)),-        void>::value>*))[2];+        void>::value>::type*))[2]; +#else // defined(ASIO_HAS_DECLTYPE)+ template <typename>+char (&buffer_sequence_end_helper(...))[2];++template <typename T>+char buffer_sequence_end_helper(T* t,+    buffer_sequence_memfns_check<+      void (buffer_sequence_memfns_base::*)(),+      &buffer_sequence_memfns_derived<T>::end>*);++#endif // defined(ASIO_HAS_DECLTYPE)++template <typename> char (&size_memfn_helper(...))[2];  template <typename T>@@ -157,11 +187,23 @@ template <typename, typename> char (&buffer_sequence_element_type_helper(...))[2]; +#if defined(ASIO_HAS_DECLTYPE)+ template <typename T, typename Buffer> char buffer_sequence_element_type_helper(T* t,-    enable_if_t<is_convertible<+    typename enable_if<is_convertible<       decltype(*asio::buffer_sequence_begin(*t)),-        Buffer>::value>*);+        Buffer>::value>::type*);++#else // defined(ASIO_HAS_DECLTYPE)++template <typename T, typename Buffer>+char buffer_sequence_element_type_helper(+    typename T::const_iterator*,+    typename enable_if<is_convertible<+      typename T::value_type, Buffer>::value>::type*);++#endif // defined(ASIO_HAS_DECLTYPE)  template <typename> char (&const_buffers_type_typedef_helper(...))[2];
link/modules/asio-standalone/asio/include/asio/detail/is_executor.hpp view
@@ -2,7 +2,7 @@ // detail/is_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/keyword_tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/keyword_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/kqueue_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/kqueue_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -65,9 +65,11 @@   // Per-descriptor queues.   struct descriptor_state   {-    descriptor_state(bool locking, int spin_count)-      : mutex_(locking, spin_count) {}+    descriptor_state(bool locking) : mutex_(locking) {} +    friend class kqueue_reactor;+    friend class object_pool_access;+     descriptor_state* next_;     descriptor_state* prev_; @@ -170,39 +172,38 @@       per_descriptor_data& descriptor_data);    // Add a new timer queue to the reactor.-  template <typename TimeTraits, typename Allocator>-  void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+  template <typename Time_Traits>+  void add_timer_queue(timer_queue<Time_Traits>& queue);    // Remove a timer queue from the reactor.-  template <typename TimeTraits, typename Allocator>-  void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+  template <typename Time_Traits>+  void remove_timer_queue(timer_queue<Time_Traits>& queue);    // Schedule a new operation in the given timer queue to expire at the   // specified absolute time.-  template <typename TimeTraits, typename Allocator>-  void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,-      const typename TimeTraits::time_type& time,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-      wait_op* op);+  template <typename Time_Traits>+  void schedule_timer(timer_queue<Time_Traits>& queue,+      const typename Time_Traits::time_type& time,+      typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);    // Cancel the timer operations associated with the given token. Returns the   // number of operations that have been posted or dispatched.-  template <typename TimeTraits, typename Allocator>-  std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+  template <typename Time_Traits>+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& timer,       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());    // Cancel the timer operations associated with the given key.-  template <typename TimeTraits, typename Allocator>-  void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+  template <typename Time_Traits>+  void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data* timer,       void* cancellation_key);    // Move the timer operations associated with the given timer.-  template <typename TimeTraits, typename Allocator>-  void move_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+  template <typename Time_Traits>+  void move_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& target,+      typename timer_queue<Time_Traits>::per_timer_data& source);    // Run the kqueue loop.   ASIO_DECL void run(long usec, op_queue<operation>& ops);@@ -248,18 +249,11 @@   // Whether the service has been shut down.   bool shutdown_; -  // Whether I/O locking is enabled.-  const bool io_locking_;--  // How any times to spin waiting for the I/O mutex.-  const int io_locking_spin_count_;-   // Mutex to protect access to the registered descriptors.   mutex registered_descriptors_mutex_;    // Keep track of all registered descriptors.-  object_pool<descriptor_state, execution_context::allocator<void>>-    registered_descriptors_;+  object_pool<descriptor_state> registered_descriptors_; };  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/limits.hpp view
@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <limits>++#if defined(ASIO_HAS_BOOST_LIMITS)+# include <boost/limits.hpp>+#else // defined(ASIO_HAS_BOOST_LIMITS)+# include <limits>+#endif // defined(ASIO_HAS_BOOST_LIMITS)  #endif // ASIO_DETAIL_LIMITS_HPP
link/modules/asio-standalone/asio/include/asio/detail/local_free_on_block_exit.hpp view
@@ -2,7 +2,7 @@ // detail/local_free_on_block_exit.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
+ link/modules/asio-standalone/asio/include/asio/detail/macos_fenced_block.hpp view
@@ -0,0 +1,62 @@+//+// detail/macos_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP+#define ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__MACH__) && defined(__APPLE__)++#include <libkern/OSAtomic.h>+#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class macos_fenced_block+  : private noncopyable+{+public:+  enum half_t { half };+  enum full_t { full };++  // Constructor for a half fenced block.+  explicit macos_fenced_block(half_t)+  {+  }++  // Constructor for a full fenced block.+  explicit macos_fenced_block(full_t)+  {+    OSMemoryBarrier();+  }++  // Destructor.+  ~macos_fenced_block()+  {+    OSMemoryBarrier();+  }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__MACH__) && defined(__APPLE__)++#endif // ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/memory.hpp view
@@ -2,7 +2,7 @@ // detail/memory.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,20 +23,42 @@ #include "asio/detail/cstdint.hpp" #include "asio/detail/throw_exception.hpp" +#if !defined(ASIO_HAS_STD_SHARED_PTR)+# include <boost/make_shared.hpp>+# include <boost/shared_ptr.hpp>+# include <boost/weak_ptr.hpp>+#endif // !defined(ASIO_HAS_STD_SHARED_PTR)++#if !defined(ASIO_HAS_STD_ADDRESSOF)+# include <boost/utility/addressof.hpp>+#endif // !defined(ASIO_HAS_STD_ADDRESSOF)+ #if !defined(ASIO_HAS_STD_ALIGNED_ALLOC) \-  && defined(ASIO_HAS_BOOST_ALIGN)+  && defined(ASIO_HAS_BOOST_ALIGN) \+  && defined(ASIO_HAS_ALIGNOF) # include <boost/align/aligned_alloc.hpp> #endif // !defined(ASIO_HAS_STD_ALIGNED_ALLOC)        //   && defined(ASIO_HAS_BOOST_ALIGN)+       //   && defined(ASIO_HAS_ALIGNOF)  namespace asio { namespace detail { -using std::allocate_shared;+#if defined(ASIO_HAS_STD_SHARED_PTR) using std::make_shared; using std::shared_ptr; using std::weak_ptr;+#else // defined(ASIO_HAS_STD_SHARED_PTR)+using boost::make_shared;+using boost::shared_ptr;+using boost::weak_ptr;+#endif // defined(ASIO_HAS_STD_SHARED_PTR)++#if defined(ASIO_HAS_STD_ADDRESSOF) using std::addressof;+#else // defined(ASIO_HAS_STD_ADDRESSOF)+using boost::addressof;+#endif // defined(ASIO_HAS_STD_ADDRESSOF)  #if defined(ASIO_HAS_STD_TO_ADDRESS) using std::to_address;@@ -54,39 +76,23 @@ inline void* align(std::size_t alignment,     std::size_t size, void*& ptr, std::size_t& space) {+#if defined(ASIO_HAS_STD_ALIGN)   return std::align(alignment, size, ptr, space);-}--template <typename T, typename Allocator, typename... Args>-T* allocate_object(const Allocator& a, Args&&... args)-{-  typename std::allocator_traits<Allocator>::template rebind_alloc<T> alloc(a);-  T* raw = std::allocator_traits<decltype(alloc)>::allocate(alloc, 1);-#if !defined(ASIO_NO_EXCEPTIONS)-  try-#endif // !defined(ASIO_NO_EXCEPTIONS)-  {-    return new (raw) T(static_cast<Args&&>(args)...);-  }-#if !defined(ASIO_NO_EXCEPTIONS)-  catch (...)-  {-    std::allocator_traits<decltype(alloc)>::deallocate(alloc, raw, 1);-    throw;-  }-#endif // !defined(ASIO_NO_EXCEPTIONS)-}--template <typename Allocator, typename T>-void deallocate_object(const Allocator& a, T* ptr)-{-  typename std::allocator_traits<Allocator>::template rebind_alloc<T> alloc(a);-  std::allocator_traits<decltype(alloc)>::destroy(alloc, ptr);-  std::allocator_traits<decltype(alloc)>::deallocate(alloc, ptr, 1);+#else // defined(ASIO_HAS_STD_ALIGN)+	const uintptr_t intptr = reinterpret_cast<uintptr_t>(ptr);+	const uintptr_t aligned = (intptr - 1u + alignment) & -alignment;+	const std::size_t padding = aligned - intptr;+	if (size + padding > space)+    return 0;+	space -= padding;+	ptr = reinterpret_cast<void*>(aligned);+  return ptr;+#endif // defined(ASIO_HAS_STD_ALIGN) }  } // namespace detail +#if defined(ASIO_HAS_CXX11_ALLOCATORS) using std::allocator_arg_t; # define ASIO_USES_ALLOCATOR(t) \   namespace std { \@@ -97,10 +103,17 @@ # define ASIO_REBIND_ALLOC(alloc, t) \   typename std::allocator_traits<alloc>::template rebind_alloc<t>   /**/+#else // defined(ASIO_HAS_CXX11_ALLOCATORS)+struct allocator_arg_t {};+# define ASIO_USES_ALLOCATOR(t)+# define ASIO_REBIND_ALLOC(alloc, t) \+  typename alloc::template rebind<t>::other+  /**/+#endif // defined(ASIO_HAS_CXX11_ALLOCATORS)  inline void* aligned_new(std::size_t align, std::size_t size) {-#if defined(ASIO_HAS_STD_ALIGNED_ALLOC)+#if defined(ASIO_HAS_STD_ALIGNED_ALLOC) && defined(ASIO_HAS_ALIGNOF)   align = (align < ASIO_DEFAULT_ALIGN) ? ASIO_DEFAULT_ALIGN : align;   size = (size % align == 0) ? size : size + (align - size % align);   void* ptr = std::aligned_alloc(align, size);@@ -110,7 +123,7 @@     asio::detail::throw_exception(ex);   }   return ptr;-#elif defined(ASIO_HAS_BOOST_ALIGN)+#elif defined(ASIO_HAS_BOOST_ALIGN) && defined(ASIO_HAS_ALIGNOF)   align = (align < ASIO_DEFAULT_ALIGN) ? ASIO_DEFAULT_ALIGN : align;   size = (size % align == 0) ? size : size + (align - size % align);   void* ptr = boost::alignment::aligned_alloc(align, size);@@ -120,7 +133,7 @@     asio::detail::throw_exception(ex);   }   return ptr;-#elif defined(ASIO_MSVC)+#elif defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)   align = (align < ASIO_DEFAULT_ALIGN) ? ASIO_DEFAULT_ALIGN : align;   size = (size % align == 0) ? size : size + (align - size % align);   void* ptr = _aligned_malloc(size, align);@@ -130,23 +143,23 @@     asio::detail::throw_exception(ex);   }   return ptr;-#else // defined(ASIO_MSVC)+#else // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)   (void)align;   return ::operator new(size);-#endif // defined(ASIO_MSVC)+#endif // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF) }  inline void aligned_delete(void* ptr) {-#if defined(ASIO_HAS_STD_ALIGNED_ALLOC)+#if defined(ASIO_HAS_STD_ALIGNED_ALLOC) && defined(ASIO_HAS_ALIGNOF)   std::free(ptr);-#elif defined(ASIO_HAS_BOOST_ALIGN)+#elif defined(ASIO_HAS_BOOST_ALIGN) && defined(ASIO_HAS_ALIGNOF)   boost::alignment::aligned_free(ptr);-#elif defined(ASIO_MSVC)+#elif defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)   _aligned_free(ptr);-#else // defined(ASIO_MSVC)+#else // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF)   ::operator delete(ptr);-#endif // defined(ASIO_MSVC)+#endif // defined(ASIO_MSVC) && defined(ASIO_HAS_ALIGNOF) }  } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/mutex.hpp view
@@ -2,7 +2,7 @@ // detail/mutex.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,8 +23,10 @@ # include "asio/detail/win_mutex.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_mutex.hpp"-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # include "asio/detail/std_mutex.hpp"+#else+# error Only Windows, POSIX and std::mutex are supported! #endif  namespace asio {@@ -36,7 +38,7 @@ typedef win_mutex mutex; #elif defined(ASIO_HAS_PTHREADS) typedef posix_mutex mutex;-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) typedef std_mutex mutex; #endif 
link/modules/asio-standalone/asio/include/asio/detail/non_const_lvalue.hpp view
@@ -2,7 +2,7 @@ // detail/non_const_lvalue.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -26,13 +26,24 @@ template <typename T> struct non_const_lvalue {+#if defined(ASIO_HAS_MOVE)   explicit non_const_lvalue(T& t)-    : value(static_cast<conditional_t<-        is_same<T, decay_t<T>>::value, decay_t<T>&, T&&>>(t))+    : value(static_cast<typename conditional<+        is_same<T, typename decay<T>::type>::value,+          typename decay<T>::type&, T&&>::type>(t))   {   } -  conditional_t<is_same<T, decay_t<T>>::value, decay_t<T>&, decay_t<T>> value;+  typename conditional<is_same<T, typename decay<T>::type>::value,+      typename decay<T>::type&, typename decay<T>::type>::type value;+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+  explicit non_const_lvalue(const typename decay<T>::type& t)+    : value(t)+  {+  }++  typename decay<T>::type value;+#endif // defined(ASIO_HAS_MOVE) };  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/noncopyable.hpp view
@@ -2,7 +2,7 @@ // detail/noncopyable.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/null_event.hpp view
@@ -2,7 +2,7 @@ // detail/null_event.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/null_fenced_block.hpp view
@@ -2,7 +2,7 @@ // detail/null_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/null_global.hpp view
@@ -2,7 +2,7 @@ // detail/null_global.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/null_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/null_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -39,12 +39,6 @@   // Destructor.   ~null_mutex()   {-  }--  // Try to lock the mutex.-  bool try_lock()-  {-    return true;   }    // Lock the mutex.
link/modules/asio-standalone/asio/include/asio/detail/null_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/null_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/null_signal_blocker.hpp view
@@ -2,7 +2,7 @@ // detail/null_signal_blocker.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/null_socket_service.hpp view
@@ -2,7 +2,7 @@ // detail/null_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -33,7 +33,7 @@  template <typename Protocol> class null_socket_service :-  public execution_context_service_base<null_socket_service<Protocol>>+  public execution_context_service_base<null_socket_service<Protocol> > { public:   // The protocol type.@@ -52,7 +52,7 @@    // Constructor.   null_socket_service(execution_context& context)-    : execution_context_service_base<null_socket_service<Protocol>>(context)+    : execution_context_service_base<null_socket_service<Protocol> >(context)   {   } 
link/modules/asio-standalone/asio/include/asio/detail/null_static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/null_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -33,12 +33,6 @@   // Initialise the mutex.   void init()   {-  }--  // Try to lock the mutex without blocking.-  bool try_lock()-  {-    return true;   }    // Lock the mutex.
link/modules/asio-standalone/asio/include/asio/detail/null_thread.hpp view
@@ -2,7 +2,7 @@ // detail/null_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,7 @@  #if !defined(ASIO_HAS_THREADS) +#include "asio/detail/noncopyable.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" @@ -28,13 +29,9 @@ namespace detail {  class null_thread+  : private noncopyable { public:-  // Construct in a non-joinable state.-  null_thread() noexcept-  {-  }-   // Constructor.   template <typename Function>   null_thread(Function, unsigned int = 0)@@ -43,34 +40,9 @@         asio::error::operation_not_supported, "thread");   } -  // Construct with custom allocator.-  template <typename Allocator, typename Function>-  null_thread(allocator_arg_t, const Allocator&, Function, unsigned int = 0)-  {-    asio::detail::throw_error(-        asio::error::operation_not_supported, "thread");-  }--  // Move constructor.-  null_thread(null_thread&& other) noexcept-  {-  }-   // Destructor.   ~null_thread()   {-  }--  // Move assignment.-  null_thread& operator=(null_thread&& other) noexcept-  {-    return *this;-  }--  // Whether the thread can be joined.-  bool joinable() const-  {-    return false;   }    // Wait for the thread to exit.
link/modules/asio-standalone/asio/include/asio/detail/null_tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/null_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/object_pool.hpp view
@@ -2,7 +2,7 @@ // detail/object_pool.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -15,34 +15,60 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include "asio/detail/config.hpp"-#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp"  #include "asio/detail/push_options.hpp"  namespace asio { namespace detail { -template <typename Object, typename Allocator>+template <typename Object>+class object_pool;++class object_pool_access+{+public:+  template <typename Object>+  static Object* create()+  {+    return new Object;+  }++  template <typename Object, typename Arg>+  static Object* create(Arg arg)+  {+    return new Object(arg);+  }++  template <typename Object>+  static void destroy(Object* o)+  {+    delete o;+  }++  template <typename Object>+  static Object*& next(Object* o)+  {+    return o->next_;+  }++  template <typename Object>+  static Object*& prev(Object* o)+  {+    return o->prev_;+  }+};++template <typename Object> class object_pool+  : private noncopyable { public:   // Constructor.-  template <typename... Args>-  object_pool(const Allocator& allocator,-      unsigned int preallocated, Args... args)-    : allocator_(allocator),-      live_list_(0),+  object_pool()+    : live_list_(0),       free_list_(0)   {-    while (preallocated > 0)-    {-      Object* o = allocate_object<Object>(allocator_, args...);-      o->next_ = free_list_;-      o->prev_ = 0;-      free_list_ = o;-      --preallocated;-    }   }    // Destructor destroys all objects.@@ -58,20 +84,38 @@     return live_list_;   } +  // Allocate a new object.+  Object* alloc()+  {+    Object* o = free_list_;+    if (o)+      free_list_ = object_pool_access::next(free_list_);+    else+      o = object_pool_access::create<Object>();++    object_pool_access::next(o) = live_list_;+    object_pool_access::prev(o) = 0;+    if (live_list_)+      object_pool_access::prev(live_list_) = o;+    live_list_ = o;++    return o;+  }+   // Allocate a new object with an argument.-  template <typename... Args>-  Object* alloc(Args... args)+  template <typename Arg>+  Object* alloc(Arg arg)   {     Object* o = free_list_;     if (o)-      free_list_ = free_list_->next_;+      free_list_ = object_pool_access::next(free_list_);     else-      o = allocate_object<Object>(allocator_, args...);+      o = object_pool_access::create<Object>(arg); -    o->next_ = live_list_;-    o->prev_ = 0;+    object_pool_access::next(o) = live_list_;+    object_pool_access::prev(o) = 0;     if (live_list_)-      live_list_->prev_ = o;+      object_pool_access::prev(live_list_) = o;     live_list_ = o;      return o;@@ -81,36 +125,36 @@   void free(Object* o)   {     if (live_list_ == o)-      live_list_ = o->next_;+      live_list_ = object_pool_access::next(o); -    if (o->prev_)-      o->prev_->next_ = o->next_;+    if (object_pool_access::prev(o))+    {+      object_pool_access::next(object_pool_access::prev(o))+        = object_pool_access::next(o);+    } -    if (o->next_)-      o->next_->prev_ = o->prev_;+    if (object_pool_access::next(o))+    {+      object_pool_access::prev(object_pool_access::next(o))+        = object_pool_access::prev(o);+    } -    o->next_ = free_list_;-    o->prev_ = 0;+    object_pool_access::next(o) = free_list_;+    object_pool_access::prev(o) = 0;     free_list_ = o;   }  private:-  object_pool(const object_pool&) = delete;-  object_pool& operator=(const object_pool&) = delete;-   // Helper function to destroy all elements in a list.   void destroy_list(Object* list)   {     while (list)     {       Object* o = list;-      list = o->next_;-      deallocate_object(allocator_, o);+      list = object_pool_access::next(o);+      object_pool_access::destroy(o);     }   }--  // The execution_context allocator used to manage pooled object memory.-  Allocator allocator_;    // The list of live objects.   Object* live_list_;
link/modules/asio-standalone/asio/include/asio/detail/old_win_sdk_compat.hpp view
@@ -2,7 +2,7 @@ // detail/old_win_sdk_compat.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/op_queue.hpp view
@@ -2,7 +2,7 @@ // detail/op_queue.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/operation.hpp view
@@ -2,7 +2,7 @@ // detail/operation.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/pipe_select_interrupter.hpp view
@@ -2,7 +2,7 @@ // detail/pipe_select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/pop_options.hpp view
@@ -2,7 +2,7 @@ // detail/pop_options.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_event.hpp view
@@ -2,7 +2,7 @@ // detail/posix_event.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_fd_set_adapter.hpp view
@@ -2,7 +2,7 @@ // detail/posix_fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_global.hpp view
@@ -2,7 +2,7 @@ // detail/posix_global.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/posix_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -43,12 +43,6 @@   ~posix_mutex()   {     ::pthread_mutex_destroy(&mutex_); // Ignore EBUSY.-  }--  // Try to lock the mutex.-  bool try_lock()-  {-    return ::pthread_mutex_trylock(&mutex_) == 0; // Ignore EINVAL.   }    // Lock the mutex.
link/modules/asio-standalone/asio/include/asio/detail/posix_serial_port_service.hpp view
@@ -2,7 +2,7 @@ // detail/posix_serial_port_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/posix_signal_blocker.hpp view
@@ -2,7 +2,7 @@ // detail/posix_signal_blocker.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/posix_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/posix_thread.hpp view
@@ -2,7 +2,7 @@ // detail/posix_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,7 +21,7 @@  #include <cstddef> #include <pthread.h>-#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp"  #include "asio/detail/push_options.hpp" @@ -34,53 +34,20 @@ }  class posix_thread+  : private noncopyable { public:-  // Construct in a non-joinable state.-  posix_thread() noexcept-    : arg_(0)-  {-  }-   // Constructor.   template <typename Function>   posix_thread(Function f, unsigned int = 0)-    : posix_thread(std::allocator_arg, std::allocator<void>(), f)-  {-  }--  // Construct with custom allocator.-  template <typename Allocator, typename Function>-  posix_thread(allocator_arg_t, const Allocator& a,-      Function f, unsigned int = 0)-    : arg_(start_thread(allocate_object<func<Function, Allocator>>(a, f, a)))-  {-  }--  // Move constructor.-  posix_thread(posix_thread&& other) noexcept-    : arg_(other.arg_)+    : joined_(false)   {-    other.arg_ = 0;+    start_thread(new func<Function>(f));   }    // Destructor.   ASIO_DECL ~posix_thread(); -  // Move assignment.-  posix_thread& operator=(posix_thread&& other) noexcept-  {-    arg_ = other.arg_;-    other.arg_ = 0;-    return *this;-  }--  // Whether the thread can be joined.-  bool joinable() const-  {-    return !!arg_;-  }-   // Wait for the thread to exit.   ASIO_DECL void join(); @@ -95,18 +62,21 @@   public:     virtual ~func_base() {}     virtual void run() = 0;-    virtual void destroy() = 0;-    ::pthread_t thread_;   }; -  template <typename Function, typename Allocator>+  struct auto_func_base_ptr+  {+    func_base* ptr;+    ~auto_func_base_ptr() { delete ptr; }+  };++  template <typename Function>   class func     : public func_base   {   public:-    func(Function f, const Allocator& a)-      : f_(f),-        allocator_(a)+    func(Function f)+      : f_(f)     {     } @@ -115,19 +85,14 @@       f_();     } -    virtual void destroy()-    {-      deallocate_object(allocator_, this);-    }-   private:     Function f_;-    Allocator allocator_;   }; -  ASIO_DECL func_base* start_thread(func_base* arg);+  ASIO_DECL void start_thread(func_base* arg); -  func_base* arg_;+  ::pthread_t thread_;+  bool joined_; };  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/posix_tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/posix_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/push_options.hpp view
@@ -2,7 +2,7 @@ // detail/push_options.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/reactive_descriptor_service.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_descriptor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -89,7 +89,7 @@    // Move-construct a new descriptor implementation.   ASIO_DECL void move_construct(implementation_type& impl,-      implementation_type& other_impl) noexcept;+      implementation_type& other_impl) ASIO_NOEXCEPT;    // Move-assign from another descriptor implementation.   ASIO_DECL void move_assign(implementation_type& impl,@@ -212,7 +212,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -239,7 +239,7 @@     default:       p.p->ec_ = asio::error::invalid_argument;       start_op(impl, reactor::read_op, p.p,-          is_continuation, false, true, false, &io_ex, 0);+          is_continuation, false, true, &io_ex, 0);       p.v = p.p = 0;       return;     }@@ -252,8 +252,7 @@             &reactor_, &impl.reactor_data_, impl.descriptor_, op_type);     } -    start_op(impl, op_type, p.p, is_continuation,-        false, false, false, &io_ex, 0);+    start_op(impl, op_type, p.p, is_continuation, false, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -304,7 +303,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -327,7 +326,7 @@      start_op(impl, reactor::write_op, p.p, is_continuation, true,         buffer_sequence_adapter<asio::const_buffer,-          ConstBufferSequence>::all_empty(buffers), true, &io_ex, 0);+          ConstBufferSequence>::all_empty(buffers), &io_ex, 0);     p.v = p.p = 0;   } @@ -339,7 +338,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -361,7 +360,7 @@           &impl, impl.descriptor_, "async_write_some(null_buffers)"));      start_op(impl, reactor::write_op, p.p,-        is_continuation, false, false, false, &io_ex, 0);+        is_continuation, false, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -413,7 +412,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -436,7 +435,7 @@      start_op(impl, reactor::read_op, p.p, is_continuation, true,         buffer_sequence_adapter<asio::mutable_buffer,-          MutableBufferSequence>::all_empty(buffers), true, &io_ex, 0);+          MutableBufferSequence>::all_empty(buffers), &io_ex, 0);     p.v = p.p = 0;   } @@ -448,7 +447,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -470,15 +469,14 @@           &impl, impl.descriptor_, "async_read_some(null_buffers)"));      start_op(impl, reactor::read_op, p.p,-        is_continuation, false, false, false, &io_ex, 0);+        is_continuation, false, false, &io_ex, 0);     p.v = p.p = 0;   }  private:   // Start the asynchronous operation.-  ASIO_DECL void do_start_op(implementation_type& impl,-      int op_type, reactor_op* op, bool is_continuation,-      bool allow_speculative, bool noop, bool needs_non_blocking,+  ASIO_DECL void do_start_op(implementation_type& impl, int op_type,+      reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop,       void (*on_immediate)(operation* op, bool, const void*),       const void* immediate_arg); @@ -486,20 +484,19 @@   // immediate completion.   template <typename Op>   void start_op(implementation_type& impl, int op_type, Op* op,-      bool is_continuation, bool allow_speculative, bool noop,-      bool needs_non_blocking, const void* io_ex, ...)+      bool is_continuation, bool is_non_blocking, bool noop,+      const void* io_ex, ...)   {-    return do_start_op(impl, op_type, op, is_continuation, allow_speculative,-        noop, needs_non_blocking, &Op::do_immediate, io_ex);+    return do_start_op(impl, op_type, op, is_continuation,+        is_non_blocking, noop, &Op::do_immediate, io_ex);   }    // Start the asynchronous operation for handlers that are not specialised for   // immediate completion.   template <typename Op>-  void start_op(implementation_type& impl, int op_type,-      Op* op, bool is_continuation, bool allow_speculative,-      bool noop, bool needs_non_blocking, const void*,-      enable_if_t<+  void start_op(implementation_type& impl, int op_type, Op* op,+      bool is_continuation, bool is_non_blocking, bool noop, const void*,+      typename enable_if<         is_same<           typename associated_immediate_executor<             typename Op::handler_type,@@ -507,11 +504,10 @@           >::asio_associated_immediate_executor_is_unspecialised,           void         >::value-      >*)+      >::type*)   {-    return do_start_op(impl, op_type, op, is_continuation,-        allow_speculative, noop, needs_non_blocking,-        &reactor::call_post_immediate_completion, &reactor_);+    return do_start_op(impl, op_type, op, is_continuation, is_non_blocking,+        noop, &reactor::call_post_immediate_completion, &reactor_);   }    // Helper class used to implement per-operation cancellation
link/modules/asio-standalone/asio/include/asio/detail/reactive_null_buffers_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_null_buffers_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -41,7 +42,7 @@       Handler& handler, const IoExecutor& io_ex)     : reactor_op(success_ec, &reactive_null_buffers_op::do_perform,         &reactive_null_buffers_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -64,7 +65,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      // Make a copy of the handler so that the memory can be deallocated before@@ -99,7 +100,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_accept_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_accept_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -107,7 +108,7 @@     : reactive_socket_accept_op_base<Socket, Protocol>(         success_ec, socket, state, peer, protocol, peer_endpoint,         &reactive_socket_accept_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -129,7 +130,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -169,7 +170,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -195,6 +196,8 @@   handler_work<Handler, IoExecutor> work_; }; +#if defined(ASIO_HAS_MOVE)+ template <typename Protocol, typename PeerIoExecutor,     typename Handler, typename IoExecutor> class reactive_socket_move_accept_op :@@ -218,7 +221,7 @@       reactive_socket_accept_op_base<peer_socket_type, Protocol>(         success_ec, socket, state, *this, protocol, peer_endpoint,         &reactive_socket_move_accept_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -241,7 +244,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -254,8 +257,8 @@     // deallocated the memory here.     detail::move_binder2<Handler,       asio::error_code, peer_socket_type>-        handler(0, static_cast<Handler&&>(o->handler_), o->ec_,-          static_cast<peer_socket_type&&>(*o));+        handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,+          ASIO_MOVE_CAST(peer_socket_type)(*o));     p.h = asio::detail::addressof(handler.handler_);     p.reset(); @@ -284,7 +287,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -297,8 +300,8 @@     // deallocated the memory here.     detail::move_binder2<Handler,       asio::error_code, peer_socket_type>-        handler(0, static_cast<Handler&&>(o->handler_), o->ec_,-          static_cast<peer_socket_type&&>(*o));+        handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,+          ASIO_MOVE_CAST(peer_socket_type)(*o));     p.h = asio::detail::addressof(handler.handler_);     p.reset(); @@ -314,6 +317,8 @@   Handler handler_;   handler_work<Handler, IoExecutor> work_; };++#endif // defined(ASIO_HAS_MOVE)  } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_connect_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -71,7 +72,7 @@       socket_type socket, Handler& handler, const IoExecutor& io_ex)     : reactive_socket_connect_op_base(success_ec, socket,         &reactive_socket_connect_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -90,7 +91,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -128,7 +129,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recv_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -108,7 +109,7 @@       Handler& handler, const IoExecutor& io_ex)     : reactive_socket_recv_op_base<MutableBufferSequence>(success_ec, socket,         state, buffers, flags, &reactive_socket_recv_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -126,7 +127,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -163,7 +164,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_recvfrom_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -112,7 +113,7 @@     : reactive_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>(         success_ec, socket, protocol_type, buffers, endpoint, flags,         &reactive_socket_recvfrom_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -131,7 +132,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -169,7 +170,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_recvmsg_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -93,7 +94,7 @@     : reactive_socket_recvmsg_op_base<MutableBufferSequence>(         success_ec, socket, buffers, in_flags, out_flags,         &reactive_socket_recvmsg_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -112,7 +113,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -150,7 +151,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_send_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -111,7 +112,7 @@       Handler& handler, const IoExecutor& io_ex)     : reactive_socket_send_op_base<ConstBufferSequence>(success_ec, socket,         state, buffers, flags, &reactive_socket_send_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -129,7 +130,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -166,7 +167,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -186,6 +187,7 @@     w.complete(handler, handler.handler_, io_ex);     ASIO_HANDLER_INVOCATION_END;   }+  private:   Handler handler_;
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_sendto_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_sendto_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,6 +20,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -105,7 +106,7 @@     : reactive_socket_sendto_op_base<ConstBufferSequence, Endpoint>(         success_ec, socket, buffers, endpoint, flags,         &reactive_socket_sendto_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -123,7 +124,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);@@ -160,7 +161,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(o->ec_);
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_service.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -46,7 +46,7 @@  template <typename Protocol> class reactive_socket_service :-  public execution_context_service_base<reactive_socket_service<Protocol>>,+  public execution_context_service_base<reactive_socket_service<Protocol> >,   public reactive_socket_service_base { public:@@ -76,7 +76,7 @@   // Constructor.   reactive_socket_service(execution_context& context)     : execution_context_service_base<-        reactive_socket_service<Protocol>>(context),+        reactive_socket_service<Protocol> >(context),       reactive_socket_service_base(context)   {   }@@ -89,7 +89,7 @@    // Move-construct a new socket implementation.   void move_construct(implementation_type& impl,-      implementation_type& other_impl) noexcept+      implementation_type& other_impl) ASIO_NOEXCEPT   {     this->base_move_construct(impl, other_impl); @@ -284,7 +284,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -307,7 +307,7 @@           &impl, impl.socket_, "async_send_to"));      start_op(impl, reactor::write_op, p.p,-        is_continuation, true, false, true, &io_ex, 0);+        is_continuation, true, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -320,7 +320,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -341,7 +341,7 @@           &impl, impl.socket_, "async_send_to(null_buffers)"));      start_op(impl, reactor::write_op, p.p,-        is_continuation, false, false, false, &io_ex, 0);+        is_continuation, false, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -406,7 +406,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -432,7 +432,7 @@     start_op(impl,         (flags & socket_base::message_out_of_band)           ? reactor::except_op : reactor::read_op,-        p.p, is_continuation, true, false, true, &io_ex, 0);+        p.p, is_continuation, true, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -445,7 +445,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -471,7 +471,7 @@     start_op(impl,         (flags & socket_base::message_out_of_band)           ? reactor::except_op : reactor::read_op,-        p.p, is_continuation, false, false, false, &io_ex, 0);+        p.p, is_continuation, false, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -516,7 +516,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -541,6 +541,7 @@     p.v = p.p = 0;   } +#if defined(ASIO_HAS_MOVE)   // Start an asynchronous accept. The peer_endpoint object must be valid until   // the accept's handler is invoked.   template <typename PeerIoExecutor, typename Handler, typename IoExecutor>@@ -551,7 +552,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -576,6 +577,7 @@     start_accept_op(impl, p.p, is_continuation, false, &io_ex, 0);     p.v = p.p = 0;   }+#endif // defined(ASIO_HAS_MOVE)    // Connect the socket to the specified endpoint.   asio::error_code connect(implementation_type& impl,@@ -596,7 +598,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/reactive_socket_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_socket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -75,7 +75,7 @@    // Move-construct a new socket implementation.   ASIO_DECL void base_move_construct(base_implementation_type& impl,-      base_implementation_type& other_impl) noexcept;+      base_implementation_type& other_impl) ASIO_NOEXCEPT;    // Move-assign from another socket implementation.   ASIO_DECL void base_move_assign(base_implementation_type& impl,@@ -202,7 +202,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -229,7 +229,7 @@     default:       p.p->ec_ = asio::error::invalid_argument;       start_op(impl, reactor::read_op, p.p,-          is_continuation, false, true, false, &io_ex, 0);+          is_continuation, false, true, &io_ex, 0);       p.v = p.p = 0;       return;     }@@ -242,8 +242,7 @@             &reactor_, &impl.reactor_data_, impl.socket_, op_type);     } -    start_op(impl, op_type, p.p, is_continuation,-        false, false, false, &io_ex, 0);+    start_op(impl, op_type, p.p, is_continuation, false, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -290,7 +289,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -315,7 +314,7 @@     start_op(impl, reactor::write_op, p.p, is_continuation, true,         ((impl.state_ & socket_ops::stream_oriented)           && buffer_sequence_adapter<asio::const_buffer,-            ConstBufferSequence>::all_empty(buffers)), true, &io_ex, 0);+            ConstBufferSequence>::all_empty(buffers)), &io_ex, 0);     p.v = p.p = 0;   } @@ -327,7 +326,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -348,7 +347,7 @@           &impl, impl.socket_, "async_send(null_buffers)"));      start_op(impl, reactor::write_op, p.p,-        is_continuation, false, false, false, &io_ex, 0);+        is_continuation, false, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -396,7 +395,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -425,7 +424,7 @@         (flags & socket_base::message_out_of_band) == 0,         ((impl.state_ & socket_ops::stream_oriented)           && buffer_sequence_adapter<asio::mutable_buffer,-            MutableBufferSequence>::all_empty(buffers)), true, &io_ex, 0);+            MutableBufferSequence>::all_empty(buffers)), &io_ex, 0);     p.v = p.p = 0;   } @@ -438,7 +437,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -461,7 +460,7 @@     start_op(impl,         (flags & socket_base::message_out_of_band)           ? reactor::except_op : reactor::read_op,-        p.p, is_continuation, false, false, false, &io_ex, 0);+        p.p, is_continuation, false, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -507,7 +506,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -533,8 +532,7 @@         (in_flags & socket_base::message_out_of_band)           ? reactor::except_op : reactor::read_op,         p.p, is_continuation,-        (in_flags & socket_base::message_out_of_band) == 0,-        false, true, &io_ex, 0);+        (in_flags & socket_base::message_out_of_band) == 0, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -548,7 +546,7 @@     bool is_continuation =       asio_handler_cont_helpers::is_continuation(handler); -    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -575,7 +573,7 @@     start_op(impl,         (in_flags & socket_base::message_out_of_band)           ? reactor::except_op : reactor::read_op,-        p.p, is_continuation, false, false, false, &io_ex, 0);+        p.p, is_continuation, false, false, &io_ex, 0);     p.v = p.p = 0;   } @@ -591,9 +589,8 @@       const native_handle_type& native_socket, asio::error_code& ec);    // Start the asynchronous read or write operation.-  ASIO_DECL void do_start_op(base_implementation_type& impl,-      int op_type, reactor_op* op, bool is_continuation,-      bool allow_speculative, bool noop, bool needs_non_blocking,+  ASIO_DECL void do_start_op(base_implementation_type& impl, int op_type,+      reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop,       void (*on_immediate)(operation* op, bool, const void*),       const void* immediate_arg); @@ -601,20 +598,19 @@   // immediate completion.   template <typename Op>   void start_op(base_implementation_type& impl, int op_type, Op* op,-      bool is_continuation, bool allow_speculative, bool noop,-      bool needs_non_blocking, const void* io_ex, ...)+      bool is_continuation, bool is_non_blocking, bool noop,+      const void* io_ex, ...)   {-    return do_start_op(impl, op_type, op, is_continuation, allow_speculative,-        noop, needs_non_blocking, &Op::do_immediate, io_ex);+    return do_start_op(impl, op_type, op, is_continuation,+        is_non_blocking, noop, &Op::do_immediate, io_ex);   }    // Start the asynchronous operation for handlers that are not specialised for   // immediate completion.   template <typename Op>-  void start_op(base_implementation_type& impl, int op_type,-      Op* op, bool is_continuation, bool allow_speculative,-      bool noop, bool needs_non_blocking, const void*,-      enable_if_t<+  void start_op(base_implementation_type& impl, int op_type, Op* op,+      bool is_continuation, bool is_non_blocking, bool noop, const void*,+      typename enable_if<         is_same<           typename associated_immediate_executor<             typename Op::handler_type,@@ -622,11 +618,10 @@           >::asio_associated_immediate_executor_is_unspecialised,           void         >::value-      >*)+      >::type*)   {-    return do_start_op(impl, op_type, op, is_continuation,-        allow_speculative, noop, needs_non_blocking,-        &reactor::call_post_immediate_completion, &reactor_);+    return do_start_op(impl, op_type, op, is_continuation, is_non_blocking,+        noop, &reactor::call_post_immediate_completion, &reactor_);   }    // Start the asynchronous accept operation.@@ -650,7 +645,7 @@   template <typename Op>   void start_accept_op(base_implementation_type& impl, Op* op,       bool is_continuation, bool peer_is_open, const void*,-      enable_if_t<+      typename enable_if<         is_same<           typename associated_immediate_executor<             typename Op::handler_type,@@ -658,7 +653,7 @@           >::asio_associated_immediate_executor_is_unspecialised,           void         >::value-      >*)+      >::type*)   {     return do_start_accept_op(impl, op, is_continuation, peer_is_open,         &reactor::call_post_immediate_completion, &reactor_);@@ -686,7 +681,7 @@   template <typename Op>   void start_connect_op(base_implementation_type& impl, Op* op,       bool is_continuation, const void* addr, size_t addrlen, const void*,-      enable_if_t<+      typename enable_if<         is_same<           typename associated_immediate_executor<             typename Op::handler_type,@@ -694,7 +689,7 @@           >::asio_associated_immediate_executor_is_unspecialised,           void         >::value-      >*)+      >::type*)   {     return do_start_connect_op(impl, op, is_continuation, addr,         addrlen, &reactor::call_post_immediate_completion, &reactor_);@@ -705,7 +700,7 @@   {   public:     reactor_op_cancellation(reactor* r,-        reactor::per_descriptor_data* p, socket_type d, int o)+        reactor::per_descriptor_data* p, int d, int o)       : reactor_(r),         reactor_data_(p),         descriptor_(d),@@ -728,7 +723,7 @@   private:     reactor* reactor_;     reactor::per_descriptor_data* reactor_data_;-    socket_type descriptor_;+    int descriptor_;     int op_type_;   }; 
link/modules/asio-standalone/asio/include/asio/detail/reactive_wait_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactive_wait_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -41,7 +42,7 @@       Handler& handler, const IoExecutor& io_ex)     : reactor_op(success_ec, &reactive_wait_op::do_perform,         &reactive_wait_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -64,7 +65,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      // Make a copy of the handler so that the memory can be deallocated before@@ -99,7 +100,7 @@      // Take ownership of the operation's outstanding work.     immediate_handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/reactor.hpp view
@@ -2,7 +2,7 @@ // detail/reactor.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/reactor_op.hpp view
@@ -2,7 +2,7 @@ // detail/reactor_op.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/reactor_op_queue.hpp view
@@ -2,7 +2,7 @@ // detail/reactor_op_queue.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/recycling_allocator.hpp view
@@ -2,7 +2,7 @@ // detail/recycling_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -48,25 +48,16 @@    T* allocate(std::size_t n)   {-#if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)     void* p = thread_info_base::allocate(Purpose(),         thread_context::top_of_thread_call_stack(),-        sizeof(T) * n, alignof(T));-#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)-    void* p = asio::aligned_new(alignof(T), sizeof(T) * n);-#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+        sizeof(T) * n, ASIO_ALIGNOF(T));     return static_cast<T*>(p);   }    void deallocate(T* p, std::size_t n)   {-#if !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)     thread_info_base::deallocate(Purpose(),         thread_context::top_of_thread_call_stack(), p, sizeof(T) * n);-#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)-    (void)n;-    asio::aligned_delete(p);-#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)   } }; 
link/modules/asio-standalone/asio/include/asio/detail/regex_fwd.hpp view
@@ -2,7 +2,7 @@ // detail/regex_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,6 +17,18 @@  #if defined(ASIO_HAS_BOOST_REGEX) +#include <boost/regex_fwd.hpp>+#include <boost/version.hpp>+#if BOOST_VERSION >= 107600+# if defined(BOOST_REGEX_CXX03)+#  include <boost/regex/v4/match_flags.hpp>+# else // defined(BOOST_REGEX_CXX03)+#  include <boost/regex/v5/match_flags.hpp>+# endif // defined(BOOST_REGEX_CXX03)+#else // BOOST_VERSION >= 107600+# include <boost/regex/v4/match_flags.hpp>+#endif // BOOST_VERSION >= 107600+ namespace boost {  template <class BidiIterator>@@ -24,9 +36,6 @@  template <class BidiIterator, class Allocator> class match_results;--template <class CharT, class Traits>-class basic_regex;  } // namespace boost 
link/modules/asio-standalone/asio/include/asio/detail/resolve_endpoint_op.hpp view
@@ -2,7 +2,7 @@ // detail/resolve_endpoint_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/resolve_op.hpp"@@ -59,7 +60,7 @@       cancel_token_(cancel_token),       endpoint_(endpoint),       scheduler_(sched),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -77,7 +78,7 @@     {       // The operation is being run on the worker io_context. Time to perform       // the resolver operation.-+           // Perform the blocking endpoint resolution operation.       char host_name[NI_MAXHOST] = "";       char service_name[NI_MAXSERV] = "";@@ -99,7 +100,7 @@        // Take ownership of the operation's outstanding work.       handler_work<Handler, IoExecutor> w(-          static_cast<handler_work<Handler, IoExecutor>&&>(+          ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(             o->work_));        // Make a copy of the handler so that the memory can be deallocated
link/modules/asio-standalone/asio/include/asio/detail/resolve_op.hpp view
@@ -2,7 +2,7 @@ // detail/resolve_op.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/resolve_query_op.hpp view
@@ -2,7 +2,7 @@ // detail/resolve_query_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/resolve_op.hpp"@@ -60,7 +61,7 @@       cancel_token_(cancel_token),       query_(qry),       scheduler_(sched),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex),       addrinfo_(0)   {@@ -85,7 +86,7 @@     {       // The operation is being run on the worker io_context. Time to perform       // the resolver operation.-+           // Perform the blocking host resolution operation.       socket_ops::background_getaddrinfo(o->cancel_token_,           o->query_.host_name().c_str(), o->query_.service_name().c_str(),@@ -104,7 +105,7 @@        // Take ownership of the operation's outstanding work.       handler_work<Handler, IoExecutor> w(-          static_cast<handler_work<Handler, IoExecutor>&&>(+          ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(             o->work_));        // Make a copy of the handler so that the memory can be deallocated
link/modules/asio-standalone/asio/include/asio/detail/resolver_service.hpp view
@@ -2,7 +2,7 @@ // detail/resolver_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,6 +21,7 @@  #include "asio/ip/basic_resolver_query.hpp" #include "asio/ip/basic_resolver_results.hpp"+#include "asio/detail/concurrency_hint.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/resolve_endpoint_op.hpp" #include "asio/detail/resolve_query_op.hpp"@@ -33,7 +34,7 @@  template <typename Protocol> class resolver_service :-  public execution_context_service_base<resolver_service<Protocol>>,+  public execution_context_service_base<resolver_service<Protocol> >,   public resolver_service_base { public:@@ -52,7 +53,7 @@    // Constructor.   resolver_service(execution_context& context)-    : execution_context_service_base<resolver_service<Protocol>>(context),+    : execution_context_service_base<resolver_service<Protocol> >(context),       resolver_service_base(context)   {   }@@ -60,8 +61,15 @@   // Destroy all user-defined handler objects owned by the service.   void shutdown()   {+    this->base_shutdown();   } +  // Perform any fork-related housekeeping.+  void notify_fork(execution_context::fork_event fork_ev)+  {+    this->base_notify_fork(fork_ev);+  }+   // Resolve a query to a list of entries.   results_type resolve(implementation_type&, const query_type& qry,       asio::error_code& ec)@@ -86,12 +94,12 @@     typedef resolve_query_op<Protocol, Handler, IoExecutor> op;     typename op::ptr p = { asio::detail::addressof(handler),       op::ptr::allocate(handler), 0 };-    p.p = new (p.v) op(impl, qry, thread_pool_.scheduler(), handler, io_ex);+    p.p = new (p.v) op(impl, qry, scheduler_, handler, io_ex); -    ASIO_HANDLER_CREATION((thread_pool_.context(),+    ASIO_HANDLER_CREATION((scheduler_.context(),           *p.p, "resolver", &impl, 0, "async_resolve")); -    thread_pool_.start_resolve_op(p.p);+    start_resolve_op(p.p);     p.v = p.p = 0;   } @@ -119,13 +127,12 @@     typedef resolve_endpoint_op<Protocol, Handler, IoExecutor> op;     typename op::ptr p = { asio::detail::addressof(handler),       op::ptr::allocate(handler), 0 };-    p.p = new (p.v) op(impl, endpoint,-        thread_pool_.scheduler(), handler, io_ex);+    p.p = new (p.v) op(impl, endpoint, scheduler_, handler, io_ex); -    ASIO_HANDLER_CREATION((thread_pool_.context(),+    ASIO_HANDLER_CREATION((scheduler_.context(),           *p.p, "resolver", &impl, 0, "async_resolve")); -    thread_pool_.start_resolve_op(p.p);+    start_resolve_op(p.p);     p.v = p.p = 0;   } };
link/modules/asio-standalone/asio/include/asio/detail/resolver_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/resolver_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,11 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/error.hpp" #include "asio/execution_context.hpp"+#include "asio/detail/mutex.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/resolve_op.hpp"-#include "asio/detail/resolver_thread_pool.hpp" #include "asio/detail/socket_ops.hpp" #include "asio/detail/socket_types.hpp"+#include "asio/detail/scoped_ptr.hpp"+#include "asio/detail/thread.hpp"  #if defined(ASIO_HAS_IOCP) # include "asio/detail/win_iocp_io_context.hpp"@@ -48,6 +50,13 @@   // Destructor.   ASIO_DECL ~resolver_service_base(); +  // Destroy all user-defined handler objects owned by the service.+  ASIO_DECL void base_shutdown();++  // Perform any fork-related housekeeping.+  ASIO_DECL void base_notify_fork(+      execution_context::fork_event fork_ev);+   // Construct a new resolver implementation.   ASIO_DECL void construct(implementation_type& impl); @@ -82,6 +91,9 @@   ASIO_DECL void cancel(implementation_type& impl);  protected:+  // Helper function to start an asynchronous resolve operation.+  ASIO_DECL void start_resolve_op(resolve_op* op);+ #if !defined(ASIO_WINDOWS_RUNTIME)   // Helper class to perform exception-safe cleanup of addrinfo objects.   class auto_addrinfo@@ -109,8 +121,29 @@   }; #endif // !defined(ASIO_WINDOWS_RUNTIME) -  // Private thread pool used for performing asynchronous host resolution.-  resolver_thread_pool& thread_pool_;+  // Helper class to run the work scheduler in a thread.+  class work_scheduler_runner;++  // Start the work scheduler if it's not already running.+  ASIO_DECL void start_work_thread();++  // The scheduler implementation used to post completions.+#if defined(ASIO_HAS_IOCP)+  typedef class win_iocp_io_context scheduler_impl;+#else+  typedef class scheduler scheduler_impl;+#endif+  scheduler_impl& scheduler_;++private:+  // Mutex to protect access to internal data.+  asio::detail::mutex mutex_;++  // Private scheduler used for performing asynchronous host resolution.+  asio::detail::scoped_ptr<scheduler_impl> work_scheduler_;++  // Thread used for running the work io_context's run loop.+  asio::detail::scoped_ptr<asio::detail::thread> work_thread_; };  } // namespace detail
− link/modules/asio-standalone/asio/include/asio/detail/resolver_thread_pool.hpp
@@ -1,105 +0,0 @@-//-// detail/resolver_thread_pool.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DETAIL_RESOLVER_THREAD_POOL_HPP-#define ASIO_DETAIL_RESOLVER_THREAD_POOL_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/execution_context.hpp"-#include "asio/detail/mutex.hpp"-#include "asio/detail/resolve_op.hpp"-#include "asio/detail/scheduler.hpp"-#include "asio/detail/thread_group.hpp"--#if defined(ASIO_HAS_IOCP)-# include "asio/detail/win_iocp_io_context.hpp"-#else // defined(ASIO_HAS_IOCP)-# include "asio/detail/scheduler.hpp"-#endif // defined(ASIO_HAS_IOCP)--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--class resolver_thread_pool :-  public execution_context_service_base<resolver_thread_pool>-{-public:-#if defined(ASIO_HAS_IOCP)-  typedef class win_iocp_io_context scheduler_impl;-#else-  typedef class scheduler scheduler_impl;-#endif--  // Constructor.-  ASIO_DECL resolver_thread_pool(execution_context& context);--  // Destructor.-  ASIO_DECL ~resolver_thread_pool();--  // Destroy all user-defined handler objects owned by the service.-  ASIO_DECL void shutdown();--  // Perform any fork-related housekeeping.-  ASIO_DECL void notify_fork(execution_context::fork_event fork_ev);--  // Helper function to start an asynchronous resolve operation.-  ASIO_DECL void start_resolve_op(resolve_op* op);--  // Get the underlying scheduler implementation.-  scheduler_impl& scheduler()-  {-    return scheduler_;-  }--private:-  // Helper class to run the work scheduler in a thread.-  class work_scheduler_runner;--  // Start the work scheduler if it's not already running.-  ASIO_DECL void start_work_threads();--  // The scheduler implementation used to post completions.-  scheduler_impl& scheduler_;--  // Mutex to protect access to internal data.-  asio::detail::mutex mutex_;--  // Private scheduler used for performing asynchronous host resolution.-  scheduler_impl work_scheduler_;--  // Threads used for running the work scheduler's run loop.-  thread_group<execution_context::allocator<void>> work_threads_;--  // The number of threads used to run the work scheduler.-  unsigned int num_work_threads_;--  // Whether the scheduler locking is enabled.-  bool scheduler_locking_;--  // Whether the scheduler has been shut down.-  bool shutdown_;-};--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#if defined(ASIO_HEADER_ONLY)-# include "asio/detail/impl/resolver_thread_pool.ipp"-#endif // defined(ASIO_HEADER_ONLY)--#endif // ASIO_DETAIL_RESOLVER_THREAD_POOL_HPP
link/modules/asio-standalone/asio/include/asio/detail/scheduler.hpp view
@@ -2,7 +2,7 @@ // detail/scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -42,21 +42,16 @@ public:   typedef scheduler_operation operation; -  // Tag type used for constructing as an internal scheduler.-  struct internal {};-   // The type of a function used to obtain a task instance.   typedef scheduler_task* (*get_task_func_type)(       asio::execution_context&); -  // Constructor.+  // Constructor. Specifies the number of concurrent threads that are likely to+  // run the scheduler. If set to 1 certain optimisation are performed.   ASIO_DECL scheduler(asio::execution_context& ctx,-      bool own_thread = true,+      int concurrency_hint = 0, bool own_thread = true,       get_task_func_type get_task = &scheduler::get_default_task); -  // Construct as an internal scheduler.-  ASIO_DECL scheduler(internal, asio::execution_context& ctx);-   // Destructor.   ASIO_DECL ~scheduler(); @@ -140,6 +135,12 @@   // work_started() was previously called for the operations.   ASIO_DECL void abandon_operations(op_queue<operation>& ops); +  // Get the concurrency hint that was used to initialise the scheduler.+  int concurrency_hint() const+  {+    return concurrency_hint_;+  }+ private:   // The mutex type used by this scheduler.   typedef conditionally_enabled_mutex mutex;@@ -209,26 +210,23 @@   // Whether the task has been interrupted.   bool task_interrupted_; -  // Flag to indicate that the dispatcher has been stopped.-  bool stopped_;--  // Flag to indicate that the dispatcher has been shut down.-  bool shutdown_;-   // The count of unfinished work.   atomic_count outstanding_work_;    // The queue of handlers that are ready to be delivered.   op_queue<operation> op_queue_; -  // The time limit on running the scheduler task, in microseconds.-  const long task_usec_;+  // Flag to indicate that the dispatcher has been stopped.+  bool stopped_; -  // The time limit on waiting when the queue is empty, in microseconds.-  const long wait_usec_;+  // Flag to indicate that the dispatcher has been shut down.+  bool shutdown_; +  // The concurrency hint used to initialise the scheduler.+  const int concurrency_hint_;+   // The thread that is running the scheduler.-  asio::detail::thread thread_;+  asio::detail::thread* thread_; };  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/scheduler_operation.hpp view
@@ -2,7 +2,7 @@ // detail/scheduler_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/scheduler_task.hpp view
@@ -2,7 +2,7 @@ // detail/scheduler_task.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/scheduler_thread_info.hpp view
@@ -2,7 +2,7 @@ // detail/scheduler_thread_info.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/scoped_lock.hpp view
@@ -2,7 +2,7 @@ // detail/scoped_lock.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/scoped_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/scoped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/select_interrupter.hpp view
@@ -2,7 +2,7 @@ // detail/select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/select_reactor.hpp view
@@ -2,7 +2,7 @@ // detail/select_reactor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -152,39 +152,38 @@       per_descriptor_data& source_descriptor_data);    // Add a new timer queue to the reactor.-  template <typename TimeTraits, typename Allocator>-  void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+  template <typename Time_Traits>+  void add_timer_queue(timer_queue<Time_Traits>& queue);    // Remove a timer queue from the reactor.-  template <typename TimeTraits, typename Allocator>-  void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+  template <typename Time_Traits>+  void remove_timer_queue(timer_queue<Time_Traits>& queue);    // Schedule a new operation in the given timer queue to expire at the   // specified absolute time.-  template <typename TimeTraits, typename Allocator>-  void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,-      const typename TimeTraits::time_type& time,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-      wait_op* op);+  template <typename Time_Traits>+  void schedule_timer(timer_queue<Time_Traits>& queue,+      const typename Time_Traits::time_type& time,+      typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);    // Cancel the timer operations associated with the given token. Returns the   // number of operations that have been posted or dispatched.-  template <typename TimeTraits, typename Allocator>-  std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+  template <typename Time_Traits>+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& timer,       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());    // Cancel the timer operations associated with the given key.-  template <typename TimeTraits, typename Allocator>-  void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+  template <typename Time_Traits>+  void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data* timer,       void* cancellation_key);    // Move the timer operations associated with the given timer.-  template <typename TimeTraits, typename Allocator>-  void move_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& target,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& source);+  template <typename Time_Traits>+  void move_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& target,+      typename timer_queue<Time_Traits>::per_timer_data& source);    // Run select once until interrupted or events are ready to be dispatched.   ASIO_DECL void run(long usec, op_queue<operation>& ops);@@ -244,7 +243,7 @@   bool stop_thread_;    // The thread that is running the reactor loop.-  asio::detail::thread thread_;+  asio::detail::thread* thread_;    // Helper class to join and restart the reactor thread.   class restart_reactor : public operation
link/modules/asio-standalone/asio/include/asio/detail/service_registry.hpp view
@@ -2,7 +2,7 @@ // detail/service_registry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -66,10 +66,6 @@   template <typename Service>   Service& use_service(io_context& owner); -  // Create and add a service object.-  template <typename Service, typename... Args>-  Service& make_service(Args&&... args);-   // Add a service object. Throws on error, in which case ownership of the   // object is retained by the caller.   template <typename Service>@@ -80,15 +76,16 @@   bool has_service() const;  private:-  // Initialise a service's key when the key_type typedef is not available.+  // Initalise a service's key when the key_type typedef is not available.   template <typename Service>   static void init_key(execution_context::service::key& key, ...);  #if !defined(ASIO_NO_TYPEID)-  // Initialise a service's key when the key_type typedef is available.+  // Initalise a service's key when the key_type typedef is available.   template <typename Service>   static void init_key(execution_context::service::key& key,-      enable_if_t<is_base_of<typename Service::key_type, Service>::value>*);+      typename enable_if<+        is_base_of<typename Service::key_type, Service>::value>::type*); #endif // !defined(ASIO_NO_TYPEID)    // Initialise a service's key based on its id.@@ -109,20 +106,14 @@       const execution_context::service::key& key2);    // The type of a factory function used for creating a service instance.-  typedef execution_context::service*(*factory_type)(execution_context&, void*);+  typedef execution_context::service*(*factory_type)(void*);    // Factory function for creating a service instance.-  template <typename Service, typename Owner, typename... Args>-  static execution_context::service* create(-      execution_context& context, void* owner, Args&&... args);--  // Helper function to destroy an allocated service instance.-  template <typename Service>-  static void destroy_allocated(execution_context::service* service);+  template <typename Service, typename Owner>+  static execution_context::service* create(void* owner); -  // Helper function to destroy an added service instance.-  ASIO_DECL static void destroy_added(-      execution_context::service* service);+  // Destroy a service instance.+  ASIO_DECL static void destroy(execution_context::service* service);    // Helper class to manage service pointers.   struct auto_service_ptr;@@ -130,7 +121,7 @@   struct auto_service_ptr   {     execution_context::service* ptr_;-    ASIO_DECL ~auto_service_ptr();+    ~auto_service_ptr() { destroy(ptr_); }   };    // Get the service object corresponding to the specified service key. Will
link/modules/asio-standalone/asio/include/asio/detail/signal_blocker.hpp view
@@ -2,7 +2,7 @@ // detail/signal_blocker.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/signal_handler.hpp view
@@ -2,7 +2,7 @@ // detail/signal_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -36,7 +36,7 @@    signal_handler(Handler& h, const IoExecutor& io_ex)     : signal_op(&signal_handler::do_complete),-      handler_(static_cast<Handler&&>(h)),+      handler_(ASIO_MOVE_CAST(Handler)(h)),       work_(handler_, io_ex)   {   }@@ -53,7 +53,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           h->work_));      // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/signal_init.hpp view
@@ -2,7 +2,7 @@ // detail/signal_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/signal_op.hpp view
@@ -2,7 +2,7 @@ // detail/signal_op.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/signal_set_service.hpp view
@@ -2,7 +2,7 @@ // detail/signal_set_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -173,7 +173,7 @@   void async_wait(implementation_type& impl,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/socket_holder.hpp view
@@ -2,7 +2,7 @@ // detail/socket_holder.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/socket_ops.hpp view
@@ -2,7 +2,7 @@ // detail/socket_ops.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/socket_option.hpp view
@@ -2,7 +2,7 @@ // detail/socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/socket_select_interrupter.hpp view
@@ -2,7 +2,7 @@ // detail/socket_select_interrupter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/socket_types.hpp view
@@ -2,7 +2,7 @@ // detail/socket_types.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -413,11 +413,7 @@ # endif # define ASIO_OS_DEF_SA_RESTART SA_RESTART # define ASIO_OS_DEF_SA_NOCLDSTOP SA_NOCLDSTOP-# if defined(SA_NOCLDWAIT)-#  define ASIO_OS_DEF_SA_NOCLDWAIT SA_NOCLDWAIT-# else // defined(SA_NOCLDWAIT)-#  define ASIO_OS_DEF_SA_NOCLDWAIT 0-# endif // defined(SA_NOCLDWAIT)+# define ASIO_OS_DEF_SA_NOCLDWAIT SA_NOCLDWAIT #endif const int custom_socket_option_level = 0xA5100000; const int enable_connection_aborted_option = 1;
+ link/modules/asio-standalone/asio/include/asio/detail/solaris_fenced_block.hpp view
@@ -0,0 +1,62 @@+//+// detail/solaris_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP+#define ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(__sun)++#include <atomic.h>+#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class solaris_fenced_block+  : private noncopyable+{+public:+  enum half_t { half };+  enum full_t { full };++  // Constructor for a half fenced block.+  explicit solaris_fenced_block(half_t)+  {+  }++  // Constructor for a full fenced block.+  explicit solaris_fenced_block(full_t)+  {+    membar_consumer();+  }++  // Destructor.+  ~solaris_fenced_block()+  {+    membar_producer();+  }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(__sun)++#endif // ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/source_location.hpp view
@@ -2,7 +2,7 @@ // detail/source_location.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,8 +23,10 @@ # include "asio/detail/win_static_mutex.hpp" #elif defined(ASIO_HAS_PTHREADS) # include "asio/detail/posix_static_mutex.hpp"-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) # include "asio/detail/std_static_mutex.hpp"+#else+# error Only Windows and POSIX are supported! #endif  namespace asio {@@ -39,7 +41,7 @@ #elif defined(ASIO_HAS_PTHREADS) typedef posix_static_mutex static_mutex; # define ASIO_STATIC_MUTEX_INIT ASIO_POSIX_STATIC_MUTEX_INIT-#else+#elif defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR) typedef std_static_mutex static_mutex; # define ASIO_STATIC_MUTEX_INIT ASIO_STD_STATIC_MUTEX_INIT #endif
link/modules/asio-standalone/asio/include/asio/detail/std_event.hpp view
@@ -2,7 +2,7 @@ // detail/std_event.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+ #include <chrono> #include <condition_variable> #include "asio/detail/assert.hpp"@@ -179,5 +182,7 @@ } // namespace asio  #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)  #endif // ASIO_DETAIL_STD_EVENT_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_fenced_block.hpp view
@@ -2,7 +2,7 @@ // detail/std_fenced_block.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_ATOMIC)+ #include <atomic> #include "asio/detail/noncopyable.hpp" @@ -53,5 +56,7 @@ } // namespace asio  #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_ATOMIC)  #endif // ASIO_DETAIL_STD_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_global.hpp view
@@ -2,7 +2,7 @@ // detail/std_global.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_CALL_ONCE)+ #include <exception> #include <mutex> @@ -61,5 +64,7 @@ } // namespace asio  #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_CALL_ONCE)  #endif // ASIO_DETAIL_STD_GLOBAL_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/std_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+ #include <mutex> #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp"@@ -43,12 +46,6 @@   {   } -  // Try to lock the mutex.-  bool try_lock()-  {-    return mutex_.try_lock();-  }-   // Lock the mutex.   void lock()   {@@ -70,5 +67,7 @@ } // namespace asio  #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)  #endif // ASIO_DETAIL_STD_MUTEX_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/std_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)+ #include <mutex> #include "asio/detail/noncopyable.hpp" #include "asio/detail/scoped_lock.hpp"@@ -72,5 +75,7 @@ } // namespace asio  #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_MUTEX_AND_CONDVAR)  #endif // ASIO_DETAIL_STD_STATIC_MUTEX_HPP
link/modules/asio-standalone/asio/include/asio/detail/std_thread.hpp view
@@ -2,7 +2,7 @@ // detail/std_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,8 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_STD_THREAD)+ #include <thread>-#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp"  #include "asio/detail/push_options.hpp" @@ -25,14 +28,9 @@ namespace detail {  class std_thread+  : private noncopyable { public:-  // Construct in a non-joinable state.-  std_thread() noexcept-    : thread_()-  {-  }-   // Constructor.   template <typename Function>   std_thread(Function f, unsigned int = 0)@@ -40,35 +38,10 @@   {   } -  // Construct with custom allocator.-  template <typename Allocator, typename Function>-  std_thread(allocator_arg_t, const Allocator&, Function f, unsigned int = 0)-    : thread_(f)-  {-  }--  // Move constructor.-  std_thread(std_thread&& other) noexcept-    : thread_(static_cast<std::thread&&>(other.thread_))-  {-  }-   // Destructor.   ~std_thread()   {-  }--  // Move assignment.-  std_thread& operator=(std_thread&& other) noexcept-  {-    thread_ = static_cast<std::thread&&>(other.thread_);-    return *this;-  }--  // Whether the thread can be joined.-  bool joinable() const-  {-    return thread_.joinable();+    join();   }    // Wait for the thread to exit.@@ -92,5 +65,7 @@ } // namespace asio  #include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_HAS_STD_THREAD)  #endif // ASIO_DETAIL_STD_THREAD_HPP
link/modules/asio-standalone/asio/include/asio/detail/strand_executor_service.hpp view
@@ -2,7 +2,7 @@ // detail/strand_executor_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/scheduler_operation.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution.hpp" #include "asio/execution_context.hpp"@@ -89,33 +90,33 @@   // Request invocation of the given function.   template <typename Executor, typename Function>   static void execute(const implementation_type& impl, Executor& ex,-      Function&& function,-      enable_if_t<-        can_query<Executor, execution::allocator_t<void>>::value-      >* = 0);+      ASIO_MOVE_ARG(Function) function,+      typename enable_if<+        can_query<Executor, execution::allocator_t<void> >::value+      >::type* = 0);    // Request invocation of the given function.   template <typename Executor, typename Function>   static void execute(const implementation_type& impl, Executor& ex,-      Function&& function,-      enable_if_t<-        !can_query<Executor, execution::allocator_t<void>>::value-      >* = 0);+      ASIO_MOVE_ARG(Function) function,+      typename enable_if<+        !can_query<Executor, execution::allocator_t<void> >::value+      >::type* = 0);    // Request invocation of the given function.   template <typename Executor, typename Function, typename Allocator>   static void dispatch(const implementation_type& impl, Executor& ex,-      Function&& function, const Allocator& a);+      ASIO_MOVE_ARG(Function) function, const Allocator& a);    // Request invocation of the given function and return immediately.   template <typename Executor, typename Function, typename Allocator>   static void post(const implementation_type& impl, Executor& ex,-      Function&& function, const Allocator& a);+      ASIO_MOVE_ARG(Function) function, const Allocator& a);    // Request invocation of the given function and return immediately.   template <typename Executor, typename Function, typename Allocator>   static void defer(const implementation_type& impl, Executor& ex,-      Function&& function, const Allocator& a);+      ASIO_MOVE_ARG(Function) function, const Allocator& a);    // Determine whether the strand is running in the current thread.   ASIO_DECL static bool running_in_this_thread(@@ -140,7 +141,7 @@   // Helper function to request invocation of the given function.   template <typename Executor, typename Function, typename Allocator>   static void do_execute(const implementation_type& impl, Executor& ex,-      Function&& function, const Allocator& a);+      ASIO_MOVE_ARG(Function) function, const Allocator& a);    // Mutex to protect access to the service-wide state.   mutex mutex_;@@ -149,7 +150,7 @@   enum { num_mutexes = 193 };    // Pool of mutexes.-  shared_ptr<mutex> mutexes_[num_mutexes];+  scoped_ptr<mutex> mutexes_[num_mutexes];    // Extra value used when hashing to prevent recycled memory locations from   // getting the same mutex.
link/modules/asio-standalone/asio/include/asio/detail/strand_service.hpp view
@@ -2,7 +2,7 @@ // detail/strand_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,6 +20,7 @@ #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/detail/operation.hpp"+#include "asio/detail/scoped_ptr.hpp"  #include "asio/detail/push_options.hpp" @@ -123,7 +124,7 @@ #endif // defined(ASIO_STRAND_IMPLEMENTATIONS)    // Pool of implementations.-  shared_ptr<strand_impl> implementations_[num_implementations];+  scoped_ptr<strand_impl> implementations_[num_implementations];    // Extra value used when hashing to prevent recycled memory locations from   // getting the same strand implementation.
link/modules/asio-standalone/asio/include/asio/detail/string_view.hpp view
@@ -2,7 +2,7 @@ // detail/string_view.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/thread.hpp view
@@ -2,7 +2,7 @@ // detail/thread.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -29,8 +29,10 @@ # else #  include "asio/detail/win_thread.hpp" # endif-#else+#elif defined(ASIO_HAS_STD_THREAD) # include "asio/detail/std_thread.hpp"+#else+# error Only Windows, POSIX and std::thread are supported! #endif  namespace asio {@@ -48,7 +50,7 @@ # else typedef win_thread thread; # endif-#else+#elif defined(ASIO_HAS_STD_THREAD) typedef std_thread thread; #endif 
link/modules/asio-standalone/asio/include/asio/detail/thread_context.hpp view
@@ -2,7 +2,7 @@ // detail/thread_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/thread_group.hpp view
@@ -2,7 +2,7 @@ // detail/thread_group.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,7 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include "asio/detail/memory.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/thread.hpp"  #include "asio/detail/push_options.hpp"@@ -24,14 +24,12 @@ namespace asio { namespace detail { -template <typename Allocator> class thread_group { public:   // Constructor initialises an empty thread group.-  explicit thread_group(const Allocator& a)-    : allocator_(a),-      first_(0)+  thread_group()+    : first_(0)   {   } @@ -45,7 +43,7 @@   template <typename Function>   void create_thread(Function f)   {-    first_ = allocate_object<item>(allocator_, allocator_, f, first_);+    first_ = new item(f, first_);   }    // Create new threads in the group.@@ -64,7 +62,7 @@       first_->thread_.join();       item* tmp = first_;       first_ = first_->next_;-      deallocate_object(allocator_, tmp);+      delete tmp;     }   } @@ -79,8 +77,8 @@   struct item   {     template <typename Function>-    explicit item(const Allocator& a, Function f, item* next)-      : thread_(std::allocator_arg, a, f),+    explicit item(Function f, item* next)+      : thread_(f),         next_(next)     {     }@@ -88,9 +86,6 @@     asio::detail::thread thread_;     item* next_;   };--  // The allocator to be used to create items in the group.-  Allocator allocator_;    // The first thread in the group.   item* first_;
link/modules/asio-standalone/asio/include/asio/detail/thread_info_base.hpp view
@@ -2,7 +2,7 @@ // detail/thread_info_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,10 +21,12 @@ #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" -#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  && !defined(ASIO_NO_EXCEPTIONS) # include <exception> # include "asio/multiple_exceptions.hpp"-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       // && !defined(ASIO_NO_EXCEPTIONS)  #include "asio/detail/push_options.hpp" @@ -89,22 +91,14 @@     };   }; -  struct timed_cancel_tag-  {-    enum-    {-      cache_size = ASIO_RECYCLING_ALLOCATOR_CACHE_SIZE,-      begin_mem_index = parallel_group_tag::end_mem_index,-      end_mem_index = begin_mem_index + cache_size-    };-  };--  enum { max_mem_index = timed_cancel_tag::end_mem_index };+  enum { max_mem_index = parallel_group_tag::end_mem_index };    thread_info_base()-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  && !defined(ASIO_NO_EXCEPTIONS)     : has_pending_exception_(0)-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       // && !defined(ASIO_NO_EXCEPTIONS)   {     for (int i = 0; i < max_mem_index; ++i)       reusable_memory_[i] = 0;@@ -205,7 +199,8 @@    void capture_current_exception()   {-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  && !defined(ASIO_NO_EXCEPTIONS)     switch (has_pending_exception_)     {     case 0:@@ -221,21 +216,24 @@     default:       break;     }-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       // && !defined(ASIO_NO_EXCEPTIONS)   }    void rethrow_pending_exception()   {-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  && !defined(ASIO_NO_EXCEPTIONS)     if (has_pending_exception_ > 0)     {       has_pending_exception_ = 0;       std::exception_ptr ex(-          static_cast<std::exception_ptr&&>(+          ASIO_MOVE_CAST(std::exception_ptr)(             pending_exception_));       std::rethrow_exception(ex);     }-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       // && !defined(ASIO_NO_EXCEPTIONS)   }  private:@@ -246,10 +244,12 @@ #endif // defined(ASIO_HAS_IO_URING)   void* reusable_memory_[max_mem_index]; -#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  && !defined(ASIO_NO_EXCEPTIONS)   int has_pending_exception_;   std::exception_ptr pending_exception_;-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       // && !defined(ASIO_NO_EXCEPTIONS) };  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/throw_error.hpp view
@@ -2,7 +2,7 @@ // detail/throw_error.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/throw_exception.hpp view
@@ -2,7 +2,7 @@ // detail/throw_exception.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -30,7 +30,7 @@  // Declare the throw_exception function for all targets. template <typename Exception>-[[noreturn]] void throw_exception(+void throw_exception(     const Exception& e     ASIO_SOURCE_LOCATION_DEFAULTED_PARAM); 
− link/modules/asio-standalone/asio/include/asio/detail/timed_cancel_op.hpp
@@ -1,361 +0,0 @@-//-// detail/timed_cancel_op.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DETAIL_TIMED_CANCEL_OP_HPP-#define ASIO_DETAIL_TIMED_CANCEL_OP_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_cancellation_slot.hpp"-#include "asio/associator.hpp"-#include "asio/basic_waitable_timer.hpp"-#include "asio/cancellation_signal.hpp"-#include "asio/detail/atomic_count.hpp"-#include "asio/detail/completion_payload.hpp"-#include "asio/detail/completion_payload_handler.hpp"-#include "asio/detail/handler_alloc_helpers.hpp"-#include "asio/detail/type_traits.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Op, typename... Signatures>-class timed_cancel_op_handler;--template <typename Op>-class timed_cancel_timer_handler;--template <typename Handler, typename Timer, typename... Signatures>-class timed_cancel_op-{-public:-  using handler_type = Handler;--  ASIO_DEFINE_TAGGED_HANDLER_PTR(-      thread_info_base::timed_cancel_tag, timed_cancel_op);--  timed_cancel_op(Handler& handler, Timer timer,-      cancellation_type_t cancel_type)-    : ref_count_(2),-      handler_(static_cast<Handler&&>(handler)),-      timer_(static_cast<Timer&&>(timer)),-      cancellation_type_(cancel_type),-      cancel_proxy_(nullptr),-      has_payload_(false),-      has_pending_timer_wait_(true)-  {-  }--  ~timed_cancel_op()-  {-    if (has_payload_)-      payload_storage_.payload_.~payload_type();-  }--  cancellation_slot get_cancellation_slot() noexcept-  {-    return cancellation_signal_.slot();-  }--  template <typename Initiation, typename... Args>-  void start(Initiation&& initiation, Args&&... args)-  {-    using op_handler_type =-      timed_cancel_op_handler<timed_cancel_op, Signatures...>;-    op_handler_type op_handler(this);--    using timer_handler_type =-      timed_cancel_timer_handler<timed_cancel_op>;-    timer_handler_type timer_handler(this);--    associated_cancellation_slot_t<Handler> slot-      = (get_associated_cancellation_slot)(handler_);-    if (slot.is_connected())-      cancel_proxy_ = &slot.template emplace<cancel_proxy>(this);--    timer_.async_wait(static_cast<timer_handler_type&&>(timer_handler));-    async_initiate<op_handler_type, Signatures...>(-        static_cast<Initiation&&>(initiation),-        static_cast<op_handler_type&>(op_handler),-        static_cast<Args&&>(args)...);-  }--  template <typename Message>-  void handle_op(Message&& message)-  {-    if (cancel_proxy_)-      cancel_proxy_->op_ = nullptr;--    new (&payload_storage_.payload_) payload_type(-        static_cast<Message&&>(message));-    has_payload_ = true;--    if (has_pending_timer_wait_)-    {-      timer_.cancel();-      release();-    }-    else-    {-      complete();-    }-  }--  void handle_timer()-  {-    has_pending_timer_wait_ = false;--    if (has_payload_)-    {-      complete();-    }-    else-    {-      cancellation_signal_.emit(cancellation_type_);-      release();-    }-  }--  void release()-  {-    if (--ref_count_ == 0)-    {-      ptr p = { asio::detail::addressof(handler_), this, this };-      Handler handler(static_cast<Handler&&>(handler_));-      p.h = asio::detail::addressof(handler);-      p.reset();-    }-  }--  void complete()-  {-    if (--ref_count_ == 0)-    {-      ptr p = { asio::detail::addressof(handler_), this, this };-      completion_payload_handler<payload_type, Handler> handler(-          static_cast<payload_type&&>(payload_storage_.payload_), handler_);-      p.h = asio::detail::addressof(handler.handler());-      p.reset();-      handler();-    }-  }--//private:-  typedef completion_payload<Signatures...> payload_type;--  struct cancel_proxy-  {-    cancel_proxy(timed_cancel_op* op)-      : op_(op)-    {-    }--    void operator()(cancellation_type_t type)-    {-      if (op_)-        op_->cancellation_signal_.emit(type);-    }--    timed_cancel_op* op_;-  };--  // The number of handlers that share a reference to the state.-  atomic_count ref_count_;--  // The handler to be called when the operation completes.-  Handler handler_;--  // The timer used to determine when to cancel the pending operation.-  Timer timer_;--  // The cancellation signal and type used to cancel the pending operation.-  cancellation_signal cancellation_signal_;-  cancellation_type_t cancellation_type_;--  // A proxy cancel handler used to allow cancellation of the timed operation.-  cancel_proxy* cancel_proxy_;--  // Arguments to be passed to the completion handler.-  union payload_storage-  {-    payload_storage() {}-    ~payload_storage() {}--    char dummy_;-    payload_type payload_;-  } payload_storage_;--  // Whether the payload storage contains a valid payload.-  bool has_payload_;--  // Whether the asynchronous wait on the timer is still pending-  bool has_pending_timer_wait_;-};--template <typename Op, typename R, typename... Args>-class timed_cancel_op_handler<Op, R(Args...)>-{-public:-  using cancellation_slot_type = cancellation_slot;--  explicit timed_cancel_op_handler(Op* op)-    : op_(op)-  {-  }--  timed_cancel_op_handler(timed_cancel_op_handler&& other) noexcept-    : op_(other.op_)-  {-    other.op_ = nullptr;-  }--  ~timed_cancel_op_handler()-  {-    if (op_)-      op_->release();-  }--  cancellation_slot_type get_cancellation_slot() const noexcept-  {-    return op_->get_cancellation_slot();-  }--  template <typename... Args2>-  enable_if_t<-    is_constructible<completion_message<R(Args...)>, int, Args2...>::value-  > operator()(Args2&&... args)-  {-    Op* op = op_;-    op_ = nullptr;-    typedef completion_message<R(Args...)> message_type;-    op->handle_op(message_type(0, static_cast<Args2&&>(args)...));-  }--//protected:-  Op* op_;-};--template <typename Op, typename R, typename... Args, typename... Signatures>-class timed_cancel_op_handler<Op, R(Args...), Signatures...> :-  public timed_cancel_op_handler<Op, Signatures...>-{-public:-  using timed_cancel_op_handler<Op, Signatures...>::timed_cancel_op_handler;-  using timed_cancel_op_handler<Op, Signatures...>::operator();--  template <typename... Args2>-  enable_if_t<-    is_constructible<completion_message<R(Args...)>, int, Args2...>::value-  > operator()(Args2&&... args)-  {-    Op* op = this->op_;-    this->op_ = nullptr;-    typedef completion_message<R(Args...)> message_type;-    op->handle_op(message_type(0, static_cast<Args2&&>(args)...));-  }-};--template <typename Op>-class timed_cancel_timer_handler-{-public:-  using cancellation_slot_type = cancellation_slot;--  explicit timed_cancel_timer_handler(Op* op)-    : op_(op)-  {-  }--  timed_cancel_timer_handler(timed_cancel_timer_handler&& other) noexcept-    : op_(other.op_)-  {-    other.op_ = nullptr;-  }--  ~timed_cancel_timer_handler()-  {-    if (op_)-      op_->release();-  }--  cancellation_slot_type get_cancellation_slot() const noexcept-  {-    return cancellation_slot_type();-  }--  void operator()(const asio::error_code&)-  {-    Op* op = op_;-    op_ = nullptr;-    op->handle_timer();-  }--//private:-  Op* op_;-};--} // namespace detail--template <template <typename, typename> class Associator,-    typename Op, typename... Signatures, typename DefaultCandidate>-struct associator<Associator,-    detail::timed_cancel_op_handler<Op, Signatures...>, DefaultCandidate>-  : Associator<typename Op::handler_type, DefaultCandidate>-{-  static typename Associator<typename Op::handler_type, DefaultCandidate>::type-  get(const detail::timed_cancel_op_handler<Op, Signatures...>& h) noexcept-  {-    return Associator<typename Op::handler_type, DefaultCandidate>::get(-        h.op_->handler_);-  }--  static auto get(const detail::timed_cancel_op_handler<Op, Signatures...>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<typename Op::handler_type, DefaultCandidate>::get(-        h.op_->handler_, c))-  {-    return Associator<typename Op::handler_type, DefaultCandidate>::get(-        h.op_->handler_, c);-  }-};--template <template <typename, typename> class Associator,-    typename Op, typename DefaultCandidate>-struct associator<Associator,-    detail::timed_cancel_timer_handler<Op>, DefaultCandidate>-  : Associator<typename Op::handler_type, DefaultCandidate>-{-  static typename Associator<typename Op::handler_type, DefaultCandidate>::type-  get(const detail::timed_cancel_timer_handler<Op>& h) noexcept-  {-    return Associator<typename Op::handler_type, DefaultCandidate>::get(-        h.op_->handler_);-  }--  static auto get(const detail::timed_cancel_timer_handler<Op>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<typename Op::handler_type, DefaultCandidate>::get(-        h.op_->handler_, c))-  {-    return Associator<typename Op::handler_type, DefaultCandidate>::get(-        h.op_->handler_, c);-  }-};--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DETAIL_TIMED_CANCEL_OP_HPP
link/modules/asio-standalone/asio/include/asio/detail/timer_queue.hpp view
@@ -2,7 +2,7 @@ // detail/timer_queue.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -31,16 +31,16 @@ namespace asio { namespace detail { -template <typename TimeTraits, typename Allocator>+template <typename Time_Traits> class timer_queue   : public timer_queue_base { public:   // The time type.-  typedef typename TimeTraits::time_type time_type;+  typedef typename Time_Traits::time_type time_type;    // The duration type.-  typedef typename TimeTraits::duration_type duration_type;+  typedef typename Time_Traits::duration_type duration_type;    // Per-timer data.   class per_timer_data@@ -67,12 +67,10 @@   };    // Constructor.-  timer_queue(const Allocator& alloc, std::size_t heap_reserve)+  timer_queue()     : timers_(),-      heap_(alloc)+      heap_()   {-    if (heap_reserve > 0)-      heap_.reserve(heap_reserve);   }    // Add a new timer to the queue. Returns true if this is the timer that is@@ -126,8 +124,8 @@       return max_duration;      return this->to_msec(-        TimeTraits::to_posix_duration(-          TimeTraits::subtract(heap_[0].time_, TimeTraits::now())),+        Time_Traits::to_posix_duration(+          Time_Traits::subtract(heap_[0].time_, Time_Traits::now())),         max_duration);   } @@ -138,8 +136,8 @@       return max_duration;      return this->to_usec(-        TimeTraits::to_posix_duration(-          TimeTraits::subtract(heap_[0].time_, TimeTraits::now())),+        Time_Traits::to_posix_duration(+          Time_Traits::subtract(heap_[0].time_, Time_Traits::now())),         max_duration);   } @@ -148,8 +146,8 @@   {     if (!heap_.empty())     {-      const time_type now = TimeTraits::now();-      while (!heap_.empty() && !TimeTraits::less_than(now, heap_[0].time_))+      const time_type now = Time_Traits::now();+      while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0].time_))       {         per_timer_data* timer = heap_[0].timer_;         while (wait_op* op = timer->op_queue_.front())@@ -253,7 +251,7 @@     while (index > 0)     {       std::size_t parent = (index - 1) / 2;-      if (!TimeTraits::less_than(heap_[index].time_, heap_[parent].time_))+      if (!Time_Traits::less_than(heap_[index].time_, heap_[parent].time_))         break;       swap_heap(index, parent);       index = parent;@@ -267,10 +265,10 @@     while (child < heap_.size())     {       std::size_t min_child = (child + 1 == heap_.size()-          || TimeTraits::less_than(+          || Time_Traits::less_than(             heap_[child].time_, heap_[child + 1].time_))         ? child : child + 1;-      if (TimeTraits::less_than(heap_[index].time_, heap_[min_child].time_))+      if (Time_Traits::less_than(heap_[index].time_, heap_[min_child].time_))         break;       swap_heap(index, min_child);       index = min_child;@@ -305,7 +303,7 @@         swap_heap(index, heap_.size() - 1);         timer.heap_index_ = (std::numeric_limits<std::size_t>::max)();         heap_.pop_back();-        if (index > 0 && TimeTraits::less_than(+        if (index > 0 && Time_Traits::less_than(               heap_[index].time_, heap_[(index - 1) / 2].time_))           up_heap(index);         else@@ -380,9 +378,7 @@   };    // The heap of timers, with the earliest timer at the front.-  std::vector<heap_entry,-    typename std::allocator_traits<Allocator>::template-      rebind_alloc<heap_entry>> heap_;+  std::vector<heap_entry> heap_; };  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/timer_queue_base.hpp view
@@ -2,7 +2,7 @@ // detail/timer_queue_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -57,7 +57,7 @@   timer_queue_base* next_; }; -template <typename TimeTraits, typename Allocator>+template <typename Time_Traits> class timer_queue;  } // namespace detail
+ link/modules/asio-standalone/asio/include/asio/detail/timer_queue_ptime.hpp view
@@ -0,0 +1,103 @@+//+// detail/timer_queue_ptime.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP+#define ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(ASIO_HAS_BOOST_DATE_TIME)++#include "asio/time_traits.hpp"+#include "asio/detail/timer_queue.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++struct forwarding_posix_time_traits : time_traits<boost::posix_time::ptime> {};++// Template specialisation for the commonly used instantation.+template <>+class timer_queue<time_traits<boost::posix_time::ptime> >+  : public timer_queue_base+{+public:+  // The time type.+  typedef boost::posix_time::ptime time_type;++  // The duration type.+  typedef boost::posix_time::time_duration duration_type;++  // Per-timer data.+  typedef timer_queue<forwarding_posix_time_traits>::per_timer_data+    per_timer_data;++  // Constructor.+  ASIO_DECL timer_queue();++  // Destructor.+  ASIO_DECL virtual ~timer_queue();++  // Add a new timer to the queue. Returns true if this is the timer that is+  // earliest in the queue, in which case the reactor's event demultiplexing+  // function call may need to be interrupted and restarted.+  ASIO_DECL bool enqueue_timer(const time_type& time,+      per_timer_data& timer, wait_op* op);++  // Whether there are no timers in the queue.+  ASIO_DECL virtual bool empty() const;++  // Get the time for the timer that is earliest in the queue.+  ASIO_DECL virtual long wait_duration_msec(long max_duration) const;++  // Get the time for the timer that is earliest in the queue.+  ASIO_DECL virtual long wait_duration_usec(long max_duration) const;++  // Dequeue all timers not later than the current time.+  ASIO_DECL virtual void get_ready_timers(op_queue<operation>& ops);++  // Dequeue all timers.+  ASIO_DECL virtual void get_all_timers(op_queue<operation>& ops);++  // Cancel and dequeue operations for the given timer.+  ASIO_DECL std::size_t cancel_timer(+      per_timer_data& timer, op_queue<operation>& ops,+      std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());++  // Cancel and dequeue operations for the given timer and key.+  ASIO_DECL void cancel_timer_by_key(per_timer_data* timer,+      op_queue<operation>& ops, void* cancellation_key);++  // Move operations from one timer to another, empty timer.+  ASIO_DECL void move_timer(per_timer_data& target,+      per_timer_data& source);++private:+  timer_queue<forwarding_posix_time_traits> impl_;+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#if defined(ASIO_HEADER_ONLY)+# include "asio/detail/impl/timer_queue_ptime.ipp"+#endif // defined(ASIO_HEADER_ONLY)++#endif // defined(ASIO_HAS_BOOST_DATE_TIME)++#endif // ASIO_DETAIL_TIMER_QUEUE_PTIME_HPP
link/modules/asio-standalone/asio/include/asio/detail/timer_queue_set.hpp view
@@ -2,7 +2,7 @@ // detail/timer_queue_set.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/timer_scheduler.hpp view
@@ -2,7 +2,7 @@ // detail/timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/timer_scheduler_fwd.hpp view
@@ -2,7 +2,7 @@ // detail/timer_scheduler_fwd.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/type_traits.hpp view
@@ -2,7 +2,7 @@ // detail/type_traits.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,174 +16,148 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <type_traits> +#if defined(ASIO_HAS_STD_TYPE_TRAITS)+# include <type_traits>+#else // defined(ASIO_HAS_STD_TYPE_TRAITS)+# include <boost/type_traits/add_const.hpp>+# include <boost/type_traits/add_lvalue_reference.hpp>+# include <boost/type_traits/aligned_storage.hpp>+# include <boost/type_traits/alignment_of.hpp>+# include <boost/type_traits/conditional.hpp>+# include <boost/type_traits/decay.hpp>+# include <boost/type_traits/has_nothrow_copy.hpp>+# include <boost/type_traits/has_nothrow_destructor.hpp>+# include <boost/type_traits/integral_constant.hpp>+# include <boost/type_traits/is_base_of.hpp>+# include <boost/type_traits/is_class.hpp>+# include <boost/type_traits/is_const.hpp>+# include <boost/type_traits/is_convertible.hpp>+# include <boost/type_traits/is_constructible.hpp>+# include <boost/type_traits/is_copy_constructible.hpp>+# include <boost/type_traits/is_destructible.hpp>+# include <boost/type_traits/is_function.hpp>+# include <boost/type_traits/is_object.hpp>+# include <boost/type_traits/is_pointer.hpp>+# include <boost/type_traits/is_same.hpp>+# include <boost/type_traits/remove_cv.hpp>+# include <boost/type_traits/remove_pointer.hpp>+# include <boost/type_traits/remove_reference.hpp>+# include <boost/utility/declval.hpp>+# include <boost/utility/enable_if.hpp>+# include <boost/utility/result_of.hpp>+#endif // defined(ASIO_HAS_STD_TYPE_TRAITS)+ namespace asio { +#if defined(ASIO_HAS_STD_TYPE_TRAITS) using std::add_const;--template <typename T>-using add_const_t = typename std::add_const<T>::type;- using std::add_lvalue_reference;--template <typename T>-using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;--template <std::size_t N, std::size_t A>-struct aligned_storage-{-  struct type-  {-    alignas(A) unsigned char data[N];-  };-};-+#if defined(ASIO_MSVC) && (_MSC_VER < 1900)+using std::aligned_storage;+#else // defined(ASIO_MSVC) && (_MSC_VER < 1900) template <std::size_t N, std::size_t A>-using aligned_storage_t = typename aligned_storage<N, A>::type;-+struct aligned_storage { struct type { alignas(A) unsigned char data[N]; }; };+#endif // defined(ASIO_MSVC) && (_MSC_VER < 1900) using std::alignment_of;- using std::conditional;--template <bool C, typename T, typename U>-using conditional_t = typename std::conditional<C, T, U>::type;- using std::decay;--template <typename T>-using decay_t = typename std::decay<T>::type;- using std::declval;- using std::enable_if;--template <bool C, typename T = void>-using enable_if_t = typename std::enable_if<C, T>::type;- using std::false_type;- using std::integral_constant;- using std::is_base_of;- using std::is_class;- using std::is_const;- using std::is_constructible;- using std::is_convertible;- using std::is_copy_constructible;--using std::is_nothrow_default_constructible;- using std::is_destructible;- using std::is_function;--using std::is_integral;- using std::is_move_constructible;- using std::is_nothrow_copy_constructible;--using std::is_nothrow_copy_assignable;- using std::is_nothrow_destructible;--using std::is_nothrow_move_constructible;--using std::is_nothrow_move_assignable;- using std::is_object;- using std::is_pointer;- using std::is_reference;- using std::is_same;- using std::is_scalar;--using std::is_unsigned;- using std::remove_cv;- template <typename T>-using remove_cv_t = typename std::remove_cv<T>::type;--template <typename T>-struct remove_cvref :-  std::remove_cv<typename std::remove_reference<T>::type> {};--template <typename T>-using remove_cvref_t = typename remove_cvref<T>::type;-+struct remove_cvref : remove_cv<typename std::remove_reference<T>::type> {}; using std::remove_pointer;--template <typename T>-using remove_pointer_t = typename std::remove_pointer<T>::type;- using std::remove_reference;--template <typename T>-using remove_reference_t = typename std::remove_reference<T>::type;- #if defined(ASIO_HAS_STD_INVOKE_RESULT)- template <typename> struct result_of;- template <typename F, typename... Args> struct result_of<F(Args...)> : std::invoke_result<F, Args...> {};--template <typename T>-using result_of_t = typename result_of<T>::type;- #else // defined(ASIO_HAS_STD_INVOKE_RESULT)- using std::result_of;--template <typename T>-using result_of_t = typename std::result_of<T>::type;- #endif // defined(ASIO_HAS_STD_INVOKE_RESULT)- using std::true_type;+#else // defined(ASIO_HAS_STD_TYPE_TRAITS)+using boost::add_const;+using boost::add_lvalue_reference;+using boost::aligned_storage;+using boost::alignment_of;+template <bool Condition, typename Type = void>+struct enable_if : boost::enable_if_c<Condition, Type> {};+using boost::conditional;+using boost::decay;+using boost::declval;+using boost::false_type;+using boost::integral_constant;+using boost::is_base_of;+using boost::is_class;+using boost::is_const;+using boost::is_constructible;+using boost::is_convertible;+using boost::is_copy_constructible;+using boost::is_destructible;+using boost::is_function;+#if defined(ASIO_HAS_MOVE)+template <typename T>+struct is_move_constructible : false_type {};+#else // defined(ASIO_HAS_MOVE)+template <typename T>+struct is_move_constructible : is_copy_constructible<T> {};+#endif // defined(ASIO_HAS_MOVE)+template <typename T>+struct is_nothrow_copy_constructible : boost::has_nothrow_copy<T> {};+template <typename T>+struct is_nothrow_destructible : boost::has_nothrow_destructor<T> {};+using boost::is_object;+using boost::is_pointer;+using boost::is_reference;+using boost::is_same;+using boost::is_scalar;+using boost::remove_cv;+template <typename T>+struct remove_cvref : remove_cv<typename boost::remove_reference<T>::type> {};+using boost::remove_pointer;+using boost::remove_reference;+using boost::result_of;+using boost::true_type;+#endif // defined(ASIO_HAS_STD_TYPE_TRAITS) -template <typename> struct void_type-{-  typedef void type;-};+template <typename> struct void_type { typedef void type; }; -template <typename T>-using void_t = typename void_type<T>::type;+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)  template <typename...> struct conjunction : true_type {};- template <typename T> struct conjunction<T> : T {};+template <typename Head, typename... Tail> struct conjunction<Head, Tail...> :+  conditional<Head::value, conjunction<Tail...>, Head>::type {}; -template <typename Head, typename... Tail>-struct conjunction<Head, Tail...> :-  conditional_t<Head::value, conjunction<Tail...>, Head> {};+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)  struct defaulted_constraint {-  constexpr defaulted_constraint() {}+  ASIO_CONSTEXPR defaulted_constraint() {} };  template <bool Condition, typename Type = int>-struct constraint : std::enable_if<Condition, Type> {};--template <bool Condition, typename Type = int>-using constraint_t = typename constraint<Condition, Type>::type;--template <typename T>-struct type_identity { typedef T type; };--template <typename T>-using type_identity_t = typename type_identity<T>::type;+struct constraint : enable_if<Condition, Type> {};  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/detail/utility.hpp view
@@ -2,7 +2,7 @@ // detail/utility.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -27,7 +27,7 @@ using std::index_sequence_for; using std::make_index_sequence; -#else // defined(ASIO_HAS_STD_INDEX_SEQUENCE)+#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)  template <std::size_t...> struct index_sequence@@ -38,7 +38,7 @@ struct join_index_sequences;  template <std::size_t... I, std::size_t... J>-struct join_index_sequences<index_sequence<I...>, index_sequence<J...>>+struct join_index_sequences<index_sequence<I...>, index_sequence<J...> > {   using type = index_sequence<I..., J...>; };@@ -75,7 +75,7 @@ template <std::size_t N> using make_index_sequence = typename index_range<0, N>::type; -#endif // defined(ASIO_HAS_STD_INDEX_SEQUENCE)+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)  } // namespace detail } // namespace asio
+ link/modules/asio-standalone/asio/include/asio/detail/variadic_templates.hpp view
@@ -0,0 +1,294 @@+//+// detail/variadic_templates.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_VARIADIC_TEMPLATES_HPP+#define ASIO_DETAIL_VARIADIC_TEMPLATES_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)++# define ASIO_VARIADIC_TPARAMS(n) ASIO_VARIADIC_TPARAMS_##n++# define ASIO_VARIADIC_TPARAMS_1 \+  typename T1+# define ASIO_VARIADIC_TPARAMS_2 \+  typename T1, typename T2+# define ASIO_VARIADIC_TPARAMS_3 \+  typename T1, typename T2, typename T3+# define ASIO_VARIADIC_TPARAMS_4 \+  typename T1, typename T2, typename T3, typename T4+# define ASIO_VARIADIC_TPARAMS_5 \+  typename T1, typename T2, typename T3, typename T4, typename T5+# define ASIO_VARIADIC_TPARAMS_6 \+  typename T1, typename T2, typename T3, typename T4, typename T5, \+  typename T6+# define ASIO_VARIADIC_TPARAMS_7 \+  typename T1, typename T2, typename T3, typename T4, typename T5, \+  typename T6, typename T7+# define ASIO_VARIADIC_TPARAMS_8 \+  typename T1, typename T2, typename T3, typename T4, typename T5, \+  typename T6, typename T7, typename T8++# define ASIO_VARIADIC_TARGS(n) ASIO_VARIADIC_TARGS_##n++# define ASIO_VARIADIC_TARGS_1 T1+# define ASIO_VARIADIC_TARGS_2 T1, T2+# define ASIO_VARIADIC_TARGS_3 T1, T2, T3+# define ASIO_VARIADIC_TARGS_4 T1, T2, T3, T4+# define ASIO_VARIADIC_TARGS_5 T1, T2, T3, T4, T5+# define ASIO_VARIADIC_TARGS_6 T1, T2, T3, T4, T5, T6+# define ASIO_VARIADIC_TARGS_7 T1, T2, T3, T4, T5, T6, T7+# define ASIO_VARIADIC_TARGS_8 T1, T2, T3, T4, T5, T6, T7, T8++# define ASIO_VARIADIC_BYVAL_PARAMS(n) \+  ASIO_VARIADIC_BYVAL_PARAMS_##n++# define ASIO_VARIADIC_BYVAL_PARAMS_1 T1 x1+# define ASIO_VARIADIC_BYVAL_PARAMS_2 T1 x1, T2 x2+# define ASIO_VARIADIC_BYVAL_PARAMS_3 T1 x1, T2 x2, T3 x3+# define ASIO_VARIADIC_BYVAL_PARAMS_4 T1 x1, T2 x2, T3 x3, T4 x4+# define ASIO_VARIADIC_BYVAL_PARAMS_5 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5+# define ASIO_VARIADIC_BYVAL_PARAMS_6 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, \+  T6 x6+# define ASIO_VARIADIC_BYVAL_PARAMS_7 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, \+  T6 x6, T7 x7+# define ASIO_VARIADIC_BYVAL_PARAMS_8 T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, \+  T6 x6, T7 x7, T8 x8++# define ASIO_VARIADIC_BYVAL_ARGS(n) \+  ASIO_VARIADIC_BYVAL_ARGS_##n++# define ASIO_VARIADIC_BYVAL_ARGS_1 x1+# define ASIO_VARIADIC_BYVAL_ARGS_2 x1, x2+# define ASIO_VARIADIC_BYVAL_ARGS_3 x1, x2, x3+# define ASIO_VARIADIC_BYVAL_ARGS_4 x1, x2, x3, x4+# define ASIO_VARIADIC_BYVAL_ARGS_5 x1, x2, x3, x4, x5+# define ASIO_VARIADIC_BYVAL_ARGS_6 x1, x2, x3, x4, x5, x6+# define ASIO_VARIADIC_BYVAL_ARGS_7 x1, x2, x3, x4, x5, x6, x7+# define ASIO_VARIADIC_BYVAL_ARGS_8 x1, x2, x3, x4, x5, x6, x7, x8++# define ASIO_VARIADIC_CONSTREF_PARAMS(n) \+  ASIO_VARIADIC_CONSTREF_PARAMS_##n++# define ASIO_VARIADIC_CONSTREF_PARAMS_1 \+  const T1& x1+# define ASIO_VARIADIC_CONSTREF_PARAMS_2 \+  const T1& x1, const T2& x2+# define ASIO_VARIADIC_CONSTREF_PARAMS_3 \+  const T1& x1, const T2& x2, const T3& x3+# define ASIO_VARIADIC_CONSTREF_PARAMS_4 \+  const T1& x1, const T2& x2, const T3& x3, const T4& x4+# define ASIO_VARIADIC_CONSTREF_PARAMS_5 \+  const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5+# define ASIO_VARIADIC_CONSTREF_PARAMS_6 \+  const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5, \+  const T6& x6+# define ASIO_VARIADIC_CONSTREF_PARAMS_7 \+  const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5, \+  const T6& x6, const T7& x7+# define ASIO_VARIADIC_CONSTREF_PARAMS_8 \+  const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5, \+  const T6& x6, const T7& x7, const T8& x8++# define ASIO_VARIADIC_MOVE_PARAMS(n) \+  ASIO_VARIADIC_MOVE_PARAMS_##n++# define ASIO_VARIADIC_MOVE_PARAMS_1 \+  ASIO_MOVE_ARG(T1) x1+# define ASIO_VARIADIC_MOVE_PARAMS_2 \+  ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2+# define ASIO_VARIADIC_MOVE_PARAMS_3 \+  ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+  ASIO_MOVE_ARG(T3) x3+# define ASIO_VARIADIC_MOVE_PARAMS_4 \+  ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+  ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4+# define ASIO_VARIADIC_MOVE_PARAMS_5 \+  ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+  ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \+  ASIO_MOVE_ARG(T5) x5+# define ASIO_VARIADIC_MOVE_PARAMS_6 \+  ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+  ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \+  ASIO_MOVE_ARG(T5) x5, ASIO_MOVE_ARG(T6) x6+# define ASIO_VARIADIC_MOVE_PARAMS_7 \+  ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+  ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \+  ASIO_MOVE_ARG(T5) x5, ASIO_MOVE_ARG(T6) x6, \+  ASIO_MOVE_ARG(T7) x7+# define ASIO_VARIADIC_MOVE_PARAMS_8 \+  ASIO_MOVE_ARG(T1) x1, ASIO_MOVE_ARG(T2) x2, \+  ASIO_MOVE_ARG(T3) x3, ASIO_MOVE_ARG(T4) x4, \+  ASIO_MOVE_ARG(T5) x5, ASIO_MOVE_ARG(T6) x6, \+  ASIO_MOVE_ARG(T7) x7, ASIO_MOVE_ARG(T8) x8++# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n) \+  ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_##n++# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_1 \+  ASIO_MOVE_ARG(T1)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_2 \+  ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_3 \+  ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+  ASIO_MOVE_ARG(T3)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_4 \+  ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+  ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_5 \+  ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+  ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4), \+  ASIO_MOVE_ARG(T5)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_6 \+  ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+  ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4), \+  ASIO_MOVE_ARG(T5), ASIO_MOVE_ARG(T6)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_7 \+  ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+  ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4), \+  ASIO_MOVE_ARG(T5), ASIO_MOVE_ARG(T6), \+  ASIO_MOVE_ARG(T7)+# define ASIO_VARIADIC_UNNAMED_MOVE_PARAMS_8 \+  ASIO_MOVE_ARG(T1), ASIO_MOVE_ARG(T2), \+  ASIO_MOVE_ARG(T3), ASIO_MOVE_ARG(T4), \+  ASIO_MOVE_ARG(T5), ASIO_MOVE_ARG(T6), \+  ASIO_MOVE_ARG(T7), ASIO_MOVE_ARG(T8)++# define ASIO_VARIADIC_MOVE_ARGS(n) \+  ASIO_VARIADIC_MOVE_ARGS_##n++# define ASIO_VARIADIC_MOVE_ARGS_1 \+  ASIO_MOVE_CAST(T1)(x1)+# define ASIO_VARIADIC_MOVE_ARGS_2 \+  ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2)+# define ASIO_VARIADIC_MOVE_ARGS_3 \+  ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+  ASIO_MOVE_CAST(T3)(x3)+# define ASIO_VARIADIC_MOVE_ARGS_4 \+  ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+  ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4)+# define ASIO_VARIADIC_MOVE_ARGS_5 \+  ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+  ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \+  ASIO_MOVE_CAST(T5)(x5)+# define ASIO_VARIADIC_MOVE_ARGS_6 \+  ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+  ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \+  ASIO_MOVE_CAST(T5)(x5), ASIO_MOVE_CAST(T6)(x6)+# define ASIO_VARIADIC_MOVE_ARGS_7 \+  ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+  ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \+  ASIO_MOVE_CAST(T5)(x5), ASIO_MOVE_CAST(T6)(x6), \+  ASIO_MOVE_CAST(T7)(x7)+# define ASIO_VARIADIC_MOVE_ARGS_8 \+  ASIO_MOVE_CAST(T1)(x1), ASIO_MOVE_CAST(T2)(x2), \+  ASIO_MOVE_CAST(T3)(x3), ASIO_MOVE_CAST(T4)(x4), \+  ASIO_MOVE_CAST(T5)(x5), ASIO_MOVE_CAST(T6)(x6), \+  ASIO_MOVE_CAST(T7)(x7), ASIO_MOVE_CAST(T8)(x8)++# define ASIO_VARIADIC_DECLVAL(n) \+  ASIO_VARIADIC_DECLVAL_##n++# define ASIO_VARIADIC_DECLVAL_1 \+  declval<T1>()+# define ASIO_VARIADIC_DECLVAL_2 \+  declval<T1>(), declval<T2>()+# define ASIO_VARIADIC_DECLVAL_3 \+  declval<T1>(), declval<T2>(), declval<T3>()+# define ASIO_VARIADIC_DECLVAL_4 \+  declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>()+# define ASIO_VARIADIC_DECLVAL_5 \+  declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>(), \+  declval<T5>()+# define ASIO_VARIADIC_DECLVAL_6 \+  declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>(), \+  declval<T5>(), declval<T6>()+# define ASIO_VARIADIC_DECLVAL_7 \+  declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>(), \+  declval<T5>(), declval<T6>(), declval<T7>()+# define ASIO_VARIADIC_DECLVAL_8 \+  declval<T1>(), declval<T2>(), declval<T3>(), declval<T4>(), \+  declval<T5>(), declval<T6>(), declval<T7>(), declval<T8>()++# define ASIO_VARIADIC_MOVE_DECLVAL(n) \+  ASIO_VARIADIC_MOVE_DECLVAL_##n++# define ASIO_VARIADIC_MOVE_DECLVAL_1 \+  declval<ASIO_MOVE_ARG(T1)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_2 \+  declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_3 \+  declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+  declval<ASIO_MOVE_ARG(T3)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_4 \+  declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+  declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_5 \+  declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+  declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>(), \+  declval<ASIO_MOVE_ARG(T5)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_6 \+  declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+  declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>(), \+  declval<ASIO_MOVE_ARG(T5)>(), declval<ASIO_MOVE_ARG(T6)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_7 \+  declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+  declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>(), \+  declval<ASIO_MOVE_ARG(T5)>(), declval<ASIO_MOVE_ARG(T6)>(), \+  declval<ASIO_MOVE_ARG(T7)>()+# define ASIO_VARIADIC_MOVE_DECLVAL_8 \+  declval<ASIO_MOVE_ARG(T1)>(), declval<ASIO_MOVE_ARG(T2)>(), \+  declval<ASIO_MOVE_ARG(T3)>(), declval<ASIO_MOVE_ARG(T4)>(), \+  declval<ASIO_MOVE_ARG(T5)>(), declval<ASIO_MOVE_ARG(T6)>(), \+  declval<ASIO_MOVE_ARG(T7)>(), declval<ASIO_MOVE_ARG(T8)>()++# define ASIO_VARIADIC_DECAY(n) \+  ASIO_VARIADIC_DECAY_##n++# define ASIO_VARIADIC_DECAY_1 \+  typename decay<T1>::type+# define ASIO_VARIADIC_DECAY_2 \+  typename decay<T1>::type, typename decay<T2>::type+# define ASIO_VARIADIC_DECAY_3 \+  typename decay<T1>::type, typename decay<T2>::type, \+  typename decay<T3>::type+# define ASIO_VARIADIC_DECAY_4 \+  typename decay<T1>::type, typename decay<T2>::type, \+  typename decay<T3>::type, typename decay<T4>::type+# define ASIO_VARIADIC_DECAY_5 \+  typename decay<T1>::type, typename decay<T2>::type, \+  typename decay<T3>::type, typename decay<T4>::type, \+  typename decay<T5>::type+# define ASIO_VARIADIC_DECAY_6 \+  typename decay<T1>::type, typename decay<T2>::type, \+  typename decay<T3>::type, typename decay<T4>::type, \+  typename decay<T5>::type, typename decay<T6>::type+# define ASIO_VARIADIC_DECAY_7 \+  typename decay<T1>::type, typename decay<T2>::type, \+  typename decay<T3>::type, typename decay<T4>::type, \+  typename decay<T5>::type, typename decay<T6>::type, \+  typename decay<T7>::type+# define ASIO_VARIADIC_DECAY_8 \+  typename decay<T1>::type, typename decay<T2>::type, \+  typename decay<T3>::type, typename decay<T4>::type, \+  typename decay<T5>::type, typename decay<T6>::type, \+  typename decay<T7>::type, typename decay<T8>::type++# define ASIO_VARIADIC_GENERATE(m) m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8)+# define ASIO_VARIADIC_GENERATE_5(m) m(1) m(2) m(3) m(4) m(5)++#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // ASIO_DETAIL_VARIADIC_TEMPLATES_HPP
link/modules/asio-standalone/asio/include/asio/detail/wait_handler.hpp view
@@ -2,7 +2,7 @@ // detail/wait_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -36,7 +36,7 @@    wait_handler(Handler& h, const IoExecutor& io_ex)     : wait_op(&wait_handler::do_complete),-      handler_(static_cast<Handler&&>(h)),+      handler_(ASIO_MOVE_CAST(Handler)(h)),       work_(handler_, io_ex)   {   }@@ -53,7 +53,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           h->work_));      // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/wait_op.hpp view
@@ -2,7 +2,7 @@ // detail/wait_op.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/win_event.hpp view
@@ -2,7 +2,7 @@ // detail/win_event.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/win_fd_set_adapter.hpp view
@@ -2,7 +2,7 @@ // detail/win_fd_set_adapter.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
+ link/modules/asio-standalone/asio/include/asio/detail/win_fenced_block.hpp view
@@ -0,0 +1,90 @@+//+// detail/win_fenced_block.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_DETAIL_WIN_FENCED_BLOCK_HPP+#define ASIO_DETAIL_WIN_FENCED_BLOCK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if defined(ASIO_WINDOWS) && !defined(UNDER_CE)++#include "asio/detail/socket_types.hpp"+#include "asio/detail/noncopyable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace detail {++class win_fenced_block+  : private noncopyable+{+public:+  enum half_t { half };+  enum full_t { full };++  // Constructor for a half fenced block.+  explicit win_fenced_block(half_t)+  {+  }++  // Constructor for a full fenced block.+  explicit win_fenced_block(full_t)+  {+#if defined(__BORLANDC__)+    LONG barrier = 0;+    ::InterlockedExchange(&barrier, 1);+#elif defined(ASIO_MSVC) \+  && ((ASIO_MSVC < 1400) || !defined(MemoryBarrier))+# if defined(_M_IX86)+#  pragma warning(push)+#  pragma warning(disable:4793)+    LONG barrier;+    __asm { xchg barrier, eax }+#  pragma warning(pop)+# endif // defined(_M_IX86)+#else+    MemoryBarrier();+#endif+  }++  // Destructor.+  ~win_fenced_block()+  {+#if defined(__BORLANDC__)+    LONG barrier = 0;+    ::InterlockedExchange(&barrier, 1);+#elif defined(ASIO_MSVC) \+  && ((ASIO_MSVC < 1400) || !defined(MemoryBarrier))+# if defined(_M_IX86)+#  pragma warning(push)+#  pragma warning(disable:4793)+    LONG barrier;+    __asm { xchg barrier, eax }+#  pragma warning(pop)+# endif // defined(_M_IX86)+#else+    MemoryBarrier();+#endif+  }+};++} // namespace detail+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // defined(ASIO_WINDOWS) && !defined(UNDER_CE)++#endif // ASIO_DETAIL_WIN_FENCED_BLOCK_HPP
link/modules/asio-standalone/asio/include/asio/detail/win_global.hpp view
@@ -2,7 +2,7 @@ // detail/win_global.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_file_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_file_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_handle_read_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_handle_read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -24,6 +24,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -44,7 +45,7 @@       Handler& handler, const IoExecutor& io_ex)     : operation(&win_iocp_handle_read_op::do_complete),       buffers_(buffers),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -64,7 +65,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));  #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_handle_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_handle_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -152,7 +152,7 @@       const ConstBufferSequence& buffers,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -182,7 +182,7 @@       uint64_t offset, const ConstBufferSequence& buffers,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -233,7 +233,7 @@       const MutableBufferSequence& buffers,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -265,7 +265,7 @@       uint64_t offset, const MutableBufferSequence& buffers,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_handle_write_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_handle_write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -24,6 +24,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -44,7 +45,7 @@       Handler& handler, const IoExecutor& io_ex)     : operation(&win_iocp_handle_write_op::do_complete),       buffers_(buffers),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -63,7 +64,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));  #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_io_context.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_io_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/limits.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/thread.hpp" #include "asio/detail/thread_context.hpp"@@ -44,16 +45,10 @@     public thread_context { public:-  // Tag type used for constructing as an internal scheduler.-  struct internal {};--  // Constructor.-  ASIO_DECL win_iocp_io_context(-      asio::execution_context& ctx, bool own_thread = true);--  // Construct as an internal scheduler.-  ASIO_DECL win_iocp_io_context(internal,-      asio::execution_context& ctx);+  // Constructor. Specifies a concurrency hint that is passed through to the+  // underlying I/O completion port.+  ASIO_DECL win_iocp_io_context(asio::execution_context& ctx,+      int concurrency_hint = -1, bool own_thread = true);    // Destructor.   ASIO_DECL ~win_iocp_io_context();@@ -181,40 +176,45 @@       const asio::error_code& ec, DWORD bytes_transferred = 0);    // Add a new timer queue to the service.-  template <typename TimeTraits, typename Allocator>-  void add_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+  template <typename Time_Traits>+  void add_timer_queue(timer_queue<Time_Traits>& timer_queue);    // Remove a timer queue from the service.-  template <typename TimeTraits, typename Allocator>-  void remove_timer_queue(timer_queue<TimeTraits, Allocator>& timer_queue);+  template <typename Time_Traits>+  void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);    // Schedule a new operation in the given timer queue to expire at the   // specified absolute time.-  template <typename TimeTraits, typename Allocator>-  void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,-      const typename TimeTraits::time_type& time,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-      wait_op* op);+  template <typename Time_Traits>+  void schedule_timer(timer_queue<Time_Traits>& queue,+      const typename Time_Traits::time_type& time,+      typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);    // Cancel the timer associated with the given token. Returns the number of   // handlers that have been posted or dispatched.-  template <typename TimeTraits, typename Allocator>-  std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+  template <typename Time_Traits>+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& timer,       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());    // Cancel the timer operations associated with the given key.-  template <typename TimeTraits, typename Allocator>-  void cancel_timer_by_key(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data* timer,+  template <typename Time_Traits>+  void cancel_timer_by_key(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data* timer,       void* cancellation_key);    // Move the timer operations associated with the given timer.-  template <typename TimeTraits, typename Allocator>-  void move_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& to,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& from);+  template <typename Time_Traits>+  void move_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& to,+      typename timer_queue<Time_Traits>::per_timer_data& from); +  // Get the concurrency hint that was used to initialise the io_context.+  int concurrency_hint() const+  {+    return concurrency_hint_;+  }+ private: #if defined(WINVER) && (WINVER < 0x0500)   typedef DWORD dword_ptr_t;@@ -264,7 +264,7 @@    // Flag to indicate whether there is an in-flight stop event. Every event   // posted using PostQueuedCompletionStatus consumes non-paged pool, so to-  // avoid exhausting this resource we limit the number of outstanding events.+  // avoid exhausting this resouce we limit the number of outstanding events.   long stop_event_posted_;    // Flag to indicate whether the service has been shut down.@@ -308,7 +308,7 @@   friend struct timer_thread_function;    // Background thread used for processing timeouts.-  asio::detail::thread timer_thread_;+  scoped_ptr<thread> timer_thread_;    // A waitable timer object used for waiting for timeouts.   auto_handle waitable_timer_;@@ -329,7 +329,7 @@   const int concurrency_hint_;    // The thread that is running the io_context.-  asio::detail::thread thread_;+  scoped_ptr<thread> thread_; };  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_null_buffers_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_null_buffers_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -45,7 +46,7 @@         &win_iocp_null_buffers_op::do_perform,         &win_iocp_null_buffers_op::do_complete),       cancel_token_(cancel_token),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -70,7 +71,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      // The reactor may have stored a result in the operation object.
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_operation.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_overlapped_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_overlapped_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -40,7 +41,7 @@    win_iocp_overlapped_op(Handler& handler, const IoExecutor& io_ex)     : operation(&win_iocp_overlapped_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -59,7 +60,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(ec);
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_overlapped_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_overlapped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -47,11 +47,11 @@   // Construct an win_iocp_overlapped_ptr to contain the specified handler.   template <typename Executor, typename Handler>   explicit win_iocp_overlapped_ptr(const Executor& ex,-      Handler&& handler)+      ASIO_MOVE_ARG(Handler) handler)     : ptr_(0),       iocp_service_(0)   {-    this->reset(ex, static_cast<Handler&&>(handler));+    this->reset(ex, ASIO_MOVE_CAST(Handler)(handler));   }    // Destructor automatically frees the OVERLAPPED object unless released.@@ -134,9 +134,9 @@ private:   template <typename Executor>   static win_iocp_io_context* get_iocp_service(const Executor& ex,-      enable_if_t<+      typename enable_if<         can_query<const Executor&, execution::context_t>::value-      >* = 0)+      >::type* = 0)   {     return &use_service<win_iocp_io_context>(         asio::query(ex, execution::context));@@ -144,9 +144,9 @@    template <typename Executor>   static win_iocp_io_context* get_iocp_service(const Executor& ex,-      enable_if_t<+      typename enable_if<         !can_query<const Executor&, execution::context_t>::value-      >* = 0)+      >::type* = 0)   {     return &use_service<win_iocp_io_context>(ex.context());   }
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_serial_port_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_serial_port_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_accept_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_accept_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -54,7 +55,7 @@       enable_connection_aborted_(enable_connection_aborted),       proxy_op_(0),       cancel_requested_(0),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -137,7 +138,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(ec);@@ -178,6 +179,8 @@   handler_work<Handler, IoExecutor> work_; }; +#if defined(ASIO_HAS_MOVE)+ template <typename Protocol, typename PeerIoExecutor,     typename Handler, typename IoExecutor> class win_iocp_socket_move_accept_op : public operation@@ -199,7 +202,7 @@       enable_connection_aborted_(enable_connection_aborted),       cancel_requested_(0),       proxy_op_(0),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -283,7 +286,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(ec);@@ -296,8 +299,8 @@     // deallocated the memory here.     detail::move_binder2<Handler,       asio::error_code, peer_socket_type>-        handler(0, static_cast<Handler&&>(o->handler_), ec,-          static_cast<peer_socket_type&&>(o->peer_));+        handler(0, ASIO_MOVE_CAST(Handler)(o->handler_), ec,+          ASIO_MOVE_CAST(peer_socket_type)(o->peer_));     p.h = asio::detail::addressof(handler.handler_);     p.reset(); @@ -328,6 +331,8 @@   Handler handler_;   handler_work<Handler, IoExecutor> work_; };++#endif // defined(ASIO_HAS_MOVE)  } // namespace detail } // namespace asio
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_connect_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -68,7 +69,7 @@       Handler& handler, const IoExecutor& io_ex)     : win_iocp_socket_connect_op_base(socket,         &win_iocp_socket_connect_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -97,7 +98,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      ASIO_ERROR_LOCATION(ec);
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recv_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -48,7 +49,7 @@       state_(state),       cancel_token_(cancel_token),       buffers_(buffers),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -68,7 +69,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));  #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recvfrom_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_recvfrom_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -50,7 +51,7 @@       endpoint_size_(static_cast<int>(endpoint.capacity())),       cancel_token_(cancel_token),       buffers_(buffers),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -76,7 +77,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));  #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_recvmsg_op.hpp view
@@ -1,8 +1,8 @@ // // detail/win_iocp_socket_recvmsg_op.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -50,7 +51,7 @@       cancel_token_(cancel_token),       buffers_(buffers),       out_flags_(out_flags),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -71,7 +72,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));  #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_send_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/operation.hpp"@@ -46,7 +47,7 @@     : operation(&win_iocp_socket_send_op::do_complete),       cancel_token_(cancel_token),       buffers_(buffers),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -66,7 +67,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));  #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -27,6 +27,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/operation.hpp"@@ -50,7 +51,7 @@  template <typename Protocol> class win_iocp_socket_service :-  public execution_context_service_base<win_iocp_socket_service<Protocol>>,+  public execution_context_service_base<win_iocp_socket_service<Protocol> >,   public win_iocp_socket_service_base { public:@@ -130,7 +131,7 @@   // Constructor.   win_iocp_socket_service(execution_context& context)     : execution_context_service_base<-        win_iocp_socket_service<Protocol>>(context),+        win_iocp_socket_service<Protocol> >(context),       win_iocp_socket_service_base(context)   {   }@@ -143,7 +144,7 @@    // Move-construct a new socket implementation.   void move_construct(implementation_type& impl,-      implementation_type& other_impl) noexcept+      implementation_type& other_impl) ASIO_NOEXCEPT   {     this->base_move_construct(impl, other_impl); @@ -348,7 +349,7 @@       socket_base::message_flags flags, Handler& handler,       const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -442,7 +443,7 @@       socket_base::message_flags flags, Handler& handler,       const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -474,7 +475,7 @@       endpoint_type& sender_endpoint, socket_base::message_flags flags,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -547,7 +548,7 @@   void async_accept(implementation_type& impl, Socket& peer,       endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -579,6 +580,7 @@     p.v = p.p = 0;   } +#if defined(ASIO_HAS_MOVE)   // Start an asynchronous accept. The peer and peer_endpoint objects   // must be valid until the accept's handler is invoked.   template <typename PeerIoExecutor, typename Handler, typename IoExecutor>@@ -586,7 +588,7 @@       const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -618,6 +620,7 @@         p.p->address_length(), o);     p.v = p.p = 0;   }+#endif // defined(ASIO_HAS_MOVE)    // Connect the socket to the specified endpoint.   asio::error_code connect(implementation_type& impl,@@ -635,7 +638,7 @@       const endpoint_type& peer_endpoint, Handler& handler,       const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_socket_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_socket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -27,6 +27,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/operation.hpp"@@ -95,7 +96,7 @@    // Move-construct a new socket implementation.   ASIO_DECL void base_move_construct(base_implementation_type& impl,-      base_implementation_type& other_impl) noexcept;+      base_implementation_type& other_impl) ASIO_NOEXCEPT;    // Move-assign from another socket implementation.   ASIO_DECL void base_move_assign(base_implementation_type& impl,@@ -213,7 +214,7 @@   void async_wait(base_implementation_type& impl,       socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      bool is_continuation =@@ -297,7 +298,7 @@       const ConstBufferSequence& buffers, socket_base::message_flags flags,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -373,7 +374,7 @@       const MutableBufferSequence& buffers, socket_base::message_flags flags,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -406,7 +407,7 @@       const null_buffers&, socket_base::message_flags flags,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -477,7 +478,7 @@       socket_base::message_flags& out_flags, Handler& handler,       const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -509,7 +510,7 @@       socket_base::message_flags& out_flags, Handler& handler,       const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -808,7 +809,7 @@   // Pointer to NtSetInformationFile implementation.   void* nt_set_info_; -  // Mutex to protect access to the linked list of implementations.+  // Mutex to protect access to the linked list of implementations.    asio::detail::mutex mutex_;    // The head of a linked list of all implementations.
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_thread_info.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_thread_info.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/win_iocp_wait_op.hpp view
@@ -2,7 +2,7 @@ // detail/win_iocp_wait_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/reactor_op.hpp"@@ -46,7 +47,7 @@         &win_iocp_wait_op::do_perform,         &win_iocp_wait_op::do_complete),       cancel_token_(cancel_token),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -71,7 +72,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      // The reactor may have stored a result in the operation object.
link/modules/asio-standalone/asio/include/asio/detail/win_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/win_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -41,12 +41,6 @@   ~win_mutex()   {     ::DeleteCriticalSection(&crit_section_);-  }--  // Try to lock the mutex.-  bool try_lock()-  {-    return ::TryEnterCriticalSection(&crit_section_) != 0;   }    // Lock the mutex.
link/modules/asio-standalone/asio/include/asio/detail/win_object_handle_service.hpp view
@@ -2,7 +2,7 @@ // detail/win_object_handle_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -20,6 +20,7 @@  #if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) +#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/wait_handler.hpp" #include "asio/error.hpp"
link/modules/asio-standalone/asio/include/asio/detail/win_static_mutex.hpp view
@@ -2,7 +2,7 @@ // detail/win_static_mutex.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/win_thread.hpp view
@@ -2,7 +2,7 @@ // detail/win_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,7 +22,7 @@   && !defined(UNDER_CE)  #include <cstddef>-#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp" #include "asio/detail/socket_types.hpp"  #include "asio/detail/push_options.hpp"@@ -60,55 +60,22 @@ long win_thread_base<T>::terminate_threads_ = 0;  class win_thread-  : public win_thread_base<win_thread>+  : private noncopyable,+    public win_thread_base<win_thread> { public:-  // Construct in a non-joinable state.-  win_thread() noexcept-    : arg_(0)-  {-  }-   // Constructor.   template <typename Function>   win_thread(Function f, unsigned int stack_size = 0)-    : win_thread(std::allocator_arg, std::allocator<void>(), f, stack_size)-  {-  }--  // Construct with custom allocator.-  template <typename Allocator, typename Function>-  win_thread(allocator_arg_t, const Allocator& a,-      Function f, unsigned int stack_size = 0)-    : arg_(start_thread(allocate_object<func<Function, Allocator>>(a, f, a),-          stack_size))-  {-  }--  // Move constructor.-  win_thread(win_thread&& other) noexcept-    : arg_(other.arg_)+    : thread_(0),+      exit_event_(0)   {-    other.arg_ = 0;+    start_thread(new func<Function>(f), stack_size);   }    // Destructor.   ASIO_DECL ~win_thread(); -  // Move assignment.-  win_thread& operator=(win_thread&& other) noexcept-  {-    arg_ = other.arg_;-    other.arg_ = 0;-    return *this;-  }--  // Whether the thread can be joined.-  bool joinable() const-  {-    return !!arg_;-  }-   // Wait for the thread to exit.   ASIO_DECL void join(); @@ -129,20 +96,23 @@   public:     virtual ~func_base() {}     virtual void run() = 0;-    virtual void destroy() = 0;-    ::HANDLE thread_;     ::HANDLE entry_event_;     ::HANDLE exit_event_;   }; -  template <typename Function, typename Allocator>+  struct auto_func_base_ptr+  {+    func_base* ptr;+    ~auto_func_base_ptr() { delete ptr; }+  };++  template <typename Function>   class func     : public func_base   {   public:-    func(Function f, const Allocator& a)-      : f_(f),-        allocator_(a)+    func(Function f)+      : f_(f)     {     } @@ -151,20 +121,14 @@       f_();     } -    virtual void destroy()-    {-      deallocate_object(allocator_, this);-    }-   private:     Function f_;-    Allocator allocator_;   }; -  ASIO_DECL func_base* start_thread(-      func_base* arg, unsigned int stack_size);+  ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size); -  func_base* arg_;+  ::HANDLE thread_;+  ::HANDLE exit_event_; };  } // namespace detail
link/modules/asio-standalone/asio/include/asio/detail/win_tss_ptr.hpp view
@@ -2,7 +2,7 @@ // detail/win_tss_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/winapp_thread.hpp view
@@ -2,7 +2,7 @@ // detail/winapp_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,7 +19,8 @@  #if defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP) -#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp"@@ -32,62 +33,37 @@ DWORD WINAPI winapp_thread_function(LPVOID arg);  class winapp_thread+  : private noncopyable { public:-  // Construct in a non-joinable state.-  winapp_thread() noexcept-    : arg_(0)-  {-  }-   // Constructor.   template <typename Function>   winapp_thread(Function f, unsigned int = 0)-    : winapp_thread(std::allocator_arg, std::allocator<void>(), f)   {-  }--  // Construct with custom allocator.-  template <typename Allocator, typename Function>-  winapp_thread(allocator_arg_t, const Allocator& a,-      Function f, unsigned int = 0)-    : arg_(start_thread(allocate_object<func<Function, Allocator>>(a, f, a)))-  {-  }--  // Move constructor.-  winapp_thread(winapp_thread&& other) noexcept-    : arg_(other.arg_)-  {-    other.arg_ = 0;+    scoped_ptr<func_base> arg(new func<Function>(f));+    DWORD thread_id = 0;+    thread_ = ::CreateThread(0, 0, winapp_thread_function,+        arg.get(), 0, &thread_id);+    if (!thread_)+    {+      DWORD last_error = ::GetLastError();+      asio::error_code ec(last_error,+          asio::error::get_system_category());+      asio::detail::throw_error(ec, "thread");+    }+    arg.release();   }    // Destructor.   ~winapp_thread()   {-    if (arg_)-      std::terminate();-  }--  // Move assignment.-  winapp_thread& operator=(winapp_thread&& other) noexcept-  {-    arg_ = other.arg_;-    other.arg_ = 0;-    return *this;-  }--  // Whether the thread can be joined.-  bool joinable() const-  {-    return !!arg_;+    ::CloseHandle(thread_);   }    // Wait for the thread to exit.   void join()   {-    if (arg_)-      ::WaitForSingleObjectEx(arg_->thread_, INFINITE, false);+    ::WaitForSingleObjectEx(thread_, INFINITE, false);   }    // Get number of CPUs.@@ -106,18 +82,15 @@   public:     virtual ~func_base() {}     virtual void run() = 0;-    virtual void destroy() = 0;-    ::HANDLE thread_;   }; -  template <typename Function, typename Allocator>+  template <typename Function>   class func     : public func_base   {   public:-    func(Function f, const Allocator& a)-      : f_(f),-        allocator_(a)+    func(Function f)+      : f_(f)     {     } @@ -126,38 +99,18 @@       f_();     } -    virtual void destroy()-    {-      deallocate_object(allocator_, this);-    }-   private:     Function f_;-    Allocator allocator_;   }; -  func_base* start_thread(func_base* arg)-  {-    DWORD thread_id = 0;-    arg->thread_ = ::CreateThread(0, 0,-        winapp_thread_function, arg, 0, &thread_id);-    if (!arg->thread_)-    {-      arg->destroy();-      DWORD last_error = ::GetLastError();-      asio::error_code ec(last_error,-          asio::error::get_system_category());-      asio::detail::throw_error(ec, "thread");-    }-    return arg;-  }--  func_base* arg_;+  ::HANDLE thread_; };  inline DWORD WINAPI winapp_thread_function(LPVOID arg) {-  static_cast<winapp_thread::func_base*>(arg)->run();+  scoped_ptr<winapp_thread::func_base> func(+      static_cast<winapp_thread::func_base*>(arg));+  func->run();   return 0; } @@ -166,6 +119,6 @@  #include "asio/detail/pop_options.hpp" -#endif // defined(ASIO_WINDOWS) && defined(UNDER_CE)+#endif // defined(ASIO_WINDOWS) && defined(ASIO_WINDOWS_APP)  #endif // ASIO_DETAIL_WINAPP_THREAD_HPP
link/modules/asio-standalone/asio/include/asio/detail/wince_thread.hpp view
@@ -2,7 +2,7 @@ // detail/wince_thread.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,7 +19,8 @@  #if defined(ASIO_WINDOWS) && defined(UNDER_CE) -#include "asio/detail/memory.hpp"+#include "asio/detail/noncopyable.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/socket_types.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp"@@ -32,62 +33,37 @@ DWORD WINAPI wince_thread_function(LPVOID arg);  class wince_thread+  : private noncopyable { public:-  // Construct in a non-joinable state.-  wince_thread() noexcept-    : arg_(0)-  {-  }-   // Constructor.   template <typename Function>   wince_thread(Function f, unsigned int = 0)-    : wince_thread(std::allocator_arg, std::allocator<void>(), f)   {-  }--  // Construct with custom allocator.-  template <typename Allocator, typename Function>-  wince_thread(allocator_arg_t, const Allocator& a,-      Function f, unsigned int = 0)-    : arg_(start_thread(allocate_object<func<Function, Allocator>>(a, f, a)))-  {-  }--  // Move constructor.-  wince_thread(wince_thread&& other) noexcept-    : arg_(other.arg_)-  {-    other.arg_ = 0;+    scoped_ptr<func_base> arg(new func<Function>(f));+    DWORD thread_id = 0;+    thread_ = ::CreateThread(0, 0, wince_thread_function,+        arg.get(), 0, &thread_id);+    if (!thread_)+    {+      DWORD last_error = ::GetLastError();+      asio::error_code ec(last_error,+          asio::error::get_system_category());+      asio::detail::throw_error(ec, "thread");+    }+    arg.release();   }    // Destructor.   ~wince_thread()   {-    if (arg_)-      std::terminate();-  }--  // Move assignment.-  wince_thread& operator=(wince_thread&& other) noexcept-  {-    arg_ = other.arg_;-    other.arg_ = 0;-    return *this;-  }--  // Whether the thread can be joined.-  bool joinable() const-  {-    return !!arg_;+    ::CloseHandle(thread_);   }    // Wait for the thread to exit.   void join()   {-    if (arg_)-      ::WaitForSingleObject(arg_->thread_, INFINITE);+    ::WaitForSingleObject(thread_, INFINITE);   }    // Get number of CPUs.@@ -106,18 +82,15 @@   public:     virtual ~func_base() {}     virtual void run() = 0;-    virtual void destroy() = 0;-    ::HANDLE thread_;   }; -  template <typename Function, typename Allocator>+  template <typename Function>   class func     : public func_base   {   public:-    func(Function f, const Allocator& a)-      : f_(f),-        allocator_(a)+    func(Function f)+      : f_(f)     {     } @@ -126,38 +99,18 @@       f_();     } -    virtual void destroy()-    {-      deallocate_object(allocator_, this);-    }-   private:     Function f_;-    Allocator allocator_;   }; -  func_base* start_thread(func_base* arg)-  {-    DWORD thread_id = 0;-    arg->thread_ = ::CreateThread(0, 0,-        wince_thread_function, arg, 0, &thread_id);-    if (!arg->thread_)-    {-      arg->destroy();-      DWORD last_error = ::GetLastError();-      asio::error_code ec(last_error,-          asio::error::get_system_category());-      asio::detail::throw_error(ec, "thread");-    }-    return arg;-  }--  func_base* arg_;+  ::HANDLE thread_; };  inline DWORD WINAPI wince_thread_function(LPVOID arg) {-  static_cast<wince_thread::func_base*>(arg)->run();+  scoped_ptr<wince_thread::func_base> func(+      static_cast<wince_thread::func_base*>(arg));+  func->run();   return 0; } 
link/modules/asio-standalone/asio/include/asio/detail/winrt_async_manager.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_async_manager.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/winrt_async_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_async_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/winrt_resolve_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_resolve_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,6 +22,7 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp"@@ -53,7 +54,7 @@           Windows::Networking::EndpointPair^>^>(             &winrt_resolve_op::do_complete),       query_(query),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -70,7 +71,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      results_type results = results_type();
link/modules/asio-standalone/asio/include/asio/detail/winrt_resolver_service.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_resolver_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -42,7 +42,7 @@  template <typename Protocol> class winrt_resolver_service :-  public execution_context_service_base<winrt_resolver_service<Protocol>>+  public execution_context_service_base<winrt_resolver_service<Protocol> > { public:   // The implementation type of the resolver. A cancellation token is used to@@ -62,7 +62,7 @@   // Constructor.   winrt_resolver_service(execution_context& context)     : execution_context_service_base<-        winrt_resolver_service<Protocol>>(context),+        winrt_resolver_service<Protocol> >(context),       scheduler_(use_service<scheduler_impl>(context)),       async_manager_(use_service<winrt_async_manager>(context))   {
link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_connect_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_socket_connect_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp"@@ -42,7 +43,7 @@    winrt_socket_connect_op(Handler& handler, const IoExecutor& io_ex)     : winrt_async_op<void>(&winrt_socket_connect_op::do_complete),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -59,7 +60,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));      // Make a copy of the handler so that the memory can be deallocated before
link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_recv_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_socket_recv_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp"@@ -45,7 +46,7 @@     : winrt_async_op<Windows::Storage::Streams::IBuffer^>(           &winrt_socket_recv_op::do_complete),       buffers_(buffers),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -62,7 +63,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));  #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/winrt_socket_send_op.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_socket_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,6 +23,7 @@ #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_work.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/winrt_async_op.hpp"@@ -44,7 +45,7 @@       Handler& handler, const IoExecutor& io_ex)     : winrt_async_op<unsigned int>(&winrt_socket_send_op::do_complete),       buffers_(buffers),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -61,7 +62,7 @@      // Take ownership of the operation's outstanding work.     handler_work<Handler, IoExecutor> w(-        static_cast<handler_work<Handler, IoExecutor>&&>(+        ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(           o->work_));  #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
link/modules/asio-standalone/asio/include/asio/detail/winrt_ssocket_service.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_ssocket_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -33,7 +33,7 @@  template <typename Protocol> class winrt_ssocket_service :-  public execution_context_service_base<winrt_ssocket_service<Protocol>>,+  public execution_context_service_base<winrt_ssocket_service<Protocol> >,   public winrt_ssocket_service_base { public:@@ -62,7 +62,7 @@    // Constructor.   winrt_ssocket_service(execution_context& context)-    : execution_context_service_base<winrt_ssocket_service<Protocol>>(context),+    : execution_context_service_base<winrt_ssocket_service<Protocol> >(context),       winrt_ssocket_service_base(context)   {   }@@ -75,7 +75,7 @@    // Move-construct a new socket implementation.   void move_construct(implementation_type& impl,-      implementation_type& other_impl) noexcept+      implementation_type& other_impl) ASIO_NOEXCEPT   {     this->base_move_construct(impl, other_impl); 
link/modules/asio-standalone/asio/include/asio/detail/winrt_ssocket_service_base.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_ssocket_service_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -77,7 +77,7 @@    // Move-construct a new socket implementation.   ASIO_DECL void base_move_construct(base_implementation_type& impl,-      base_implementation_type& other_impl) noexcept;+      base_implementation_type& other_impl) ASIO_NOEXCEPT;    // Move-assign from another socket implementation.   ASIO_DECL void base_move_assign(base_implementation_type& impl,@@ -341,7 +341,7 @@   // The manager that keeps track of outstanding operations.   winrt_async_manager& async_manager_; -  // Mutex to protect access to the linked list of implementations.+  // Mutex to protect access to the linked list of implementations.    asio::detail::mutex mutex_;    // The head of a linked list of all implementations.
link/modules/asio-standalone/asio/include/asio/detail/winrt_timer_scheduler.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_timer_scheduler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -65,33 +65,32 @@   ASIO_DECL void init_task();    // Add a new timer queue to the reactor.-  template <typename TimeTraits, typename Allocator>-  void add_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+  template <typename Time_Traits>+  void add_timer_queue(timer_queue<Time_Traits>& queue);    // Remove a timer queue from the reactor.-  template <typename TimeTraits, typename Allocator>-  void remove_timer_queue(timer_queue<TimeTraits, Allocator>& queue);+  template <typename Time_Traits>+  void remove_timer_queue(timer_queue<Time_Traits>& queue);    // Schedule a new operation in the given timer queue to expire at the   // specified absolute time.-  template <typename TimeTraits, typename Allocator>-  void schedule_timer(timer_queue<TimeTraits, Allocator>& queue,-      const typename TimeTraits::time_type& time,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,-      wait_op* op);+  template <typename Time_Traits>+  void schedule_timer(timer_queue<Time_Traits>& queue,+      const typename Time_Traits::time_type& time,+      typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);    // Cancel the timer operations associated with the given token. Returns the   // number of operations that have been posted or dispatched.-  template <typename TimeTraits, typename Allocator>-  std::size_t cancel_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& timer,+  template <typename Time_Traits>+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& timer,       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());    // Move the timer operations associated with the given timer.-  template <typename TimeTraits, typename Allocator>-  void move_timer(timer_queue<TimeTraits, Allocator>& queue,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& to,-      typename timer_queue<TimeTraits, Allocator>::per_timer_data& from);+  template <typename Time_Traits>+  void move_timer(timer_queue<Time_Traits>& queue,+      typename timer_queue<Time_Traits>::per_timer_data& to,+      typename timer_queue<Time_Traits>::per_timer_data& from);  private:   // Run the select loop in the thread.@@ -124,7 +123,7 @@   timer_queue_set timer_queues_;    // The background thread that is waiting for timers to expire.-  asio::detail::thread thread_;+  asio::detail::thread* thread_;    // Does the background thread need to stop.   bool stop_thread_;
link/modules/asio-standalone/asio/include/asio/detail/winrt_utils.hpp view
@@ -2,7 +2,7 @@ // detail/winrt_utils.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/detail/winsock_init.hpp view
@@ -2,7 +2,7 @@ // detail/winsock_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -47,7 +47,7 @@   ASIO_DECL static void throw_on_error(data& d); }; -template <int Major = 2, int Minor = 2>+template <int Major = 2, int Minor = 0> class winsock_init : private winsock_init_base { public:
link/modules/asio-standalone/asio/include/asio/detail/work_dispatcher.hpp view
@@ -2,7 +2,7 @@ // detail/work_dispatcher.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -39,13 +39,13 @@  template <typename Handler, typename Executor> struct is_work_dispatcher_required<Handler, Executor,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_executor<Handler,           Executor>::asio_associated_executor_is_unspecialised,         void       >::value-    >> : false_type+    >::type> : false_type { }; @@ -54,14 +54,15 @@ { public:   template <typename CompletionHandler>-  work_dispatcher(CompletionHandler&& handler,+  work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler,       const Executor& handler_ex)-    : handler_(static_cast<CompletionHandler&&>(handler)),+    : handler_(ASIO_MOVE_CAST(CompletionHandler)(handler)),       executor_(asio::prefer(handler_ex,           execution::outstanding_work.tracked))   {   } +#if defined(ASIO_HAS_MOVE)   work_dispatcher(const work_dispatcher& other)     : handler_(other.handler_),       executor_(other.executor_)@@ -69,25 +70,34 @@   }    work_dispatcher(work_dispatcher&& other)-    : handler_(static_cast<Handler&&>(other.handler_)),-      executor_(static_cast<work_executor_type&&>(other.executor_))+    : handler_(ASIO_MOVE_CAST(Handler)(other.handler_)),+      executor_(ASIO_MOVE_CAST(work_executor_type)(other.executor_))   {   }+#endif // defined(ASIO_HAS_MOVE)    void operator()()   {-    associated_allocator_t<Handler> alloc((get_associated_allocator)(handler_));+    typename associated_allocator<Handler>::type alloc(+        (get_associated_allocator)(handler_));+#if defined(ASIO_NO_DEPRECATED)     asio::prefer(executor_, execution::allocator(alloc)).execute(         asio::detail::bind_handler(-          static_cast<Handler&&>(handler_)));+          ASIO_MOVE_CAST(Handler)(handler_)));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(executor_, execution::allocator(alloc)),+        asio::detail::bind_handler(+          ASIO_MOVE_CAST(Handler)(handler_)));+#endif // defined(ASIO_NO_DEPRECATED)   }  private:-  typedef decay_t<-      prefer_result_t<const Executor&,+  typedef typename decay<+      typename prefer_result<const Executor&,         execution::outstanding_work_t::tracked_t-      >-    > work_executor_type;+      >::type+    >::type work_executor_type;    Handler handler_;   work_executor_type executor_;@@ -97,16 +107,18 @@  template <typename Handler, typename Executor> class work_dispatcher<Handler, Executor,-    enable_if_t<!execution::is_executor<Executor>::value>>+    typename enable_if<!execution::is_executor<Executor>::value>::type> { public:   template <typename CompletionHandler>-  work_dispatcher(CompletionHandler&& handler, const Executor& handler_ex)+  work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler,+      const Executor& handler_ex)     : work_(handler_ex),-      handler_(static_cast<CompletionHandler&&>(handler))+      handler_(ASIO_MOVE_CAST(CompletionHandler)(handler))   {   } +#if defined(ASIO_HAS_MOVE)   work_dispatcher(const work_dispatcher& other)     : work_(other.work_),       handler_(other.handler_)@@ -114,17 +126,19 @@   }    work_dispatcher(work_dispatcher&& other)-    : work_(static_cast<executor_work_guard<Executor>&&>(other.work_)),-      handler_(static_cast<Handler&&>(other.handler_))+    : work_(ASIO_MOVE_CAST(executor_work_guard<Executor>)(other.work_)),+      handler_(ASIO_MOVE_CAST(Handler)(other.handler_))   {   }+#endif // defined(ASIO_HAS_MOVE)    void operator()()   {-    associated_allocator_t<Handler> alloc((get_associated_allocator)(handler_));+    typename associated_allocator<Handler>::type alloc(+        (get_associated_allocator)(handler_));     work_.get_executor().dispatch(         asio::detail::bind_handler(-          static_cast<Handler&&>(handler_)), alloc);+          ASIO_MOVE_CAST(Handler)(handler_)), alloc);     work_.reset();   } 
link/modules/asio-standalone/asio/include/asio/detail/wrapped_handler.hpp view
@@ -2,7 +2,7 @@ // detail/wrapped_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,8 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/bind_handler.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiate_dispatch.hpp"+#include "asio/detail/handler_invoke_helpers.hpp"  #include "asio/detail/push_options.hpp" @@ -42,43 +43,20 @@   } }; -template <typename Dispatcher, typename = void>-struct wrapped_executor-{-  typedef Dispatcher executor_type;--  static const Dispatcher& get(const Dispatcher& dispatcher) noexcept-  {-    return dispatcher;-  }-};--template <typename Dispatcher>-struct wrapped_executor<Dispatcher,-    void_type<typename Dispatcher::executor_type>>-{-  typedef typename Dispatcher::executor_type executor_type;--  static executor_type get(const Dispatcher& dispatcher) noexcept-  {-    return dispatcher.get_executor();-  }-};- template <typename Dispatcher, typename Handler,     typename IsContinuation = is_continuation_delegated> class wrapped_handler { public:   typedef void result_type;-  typedef typename wrapped_executor<Dispatcher>::executor_type executor_type;    wrapped_handler(Dispatcher dispatcher, Handler& handler)     : dispatcher_(dispatcher),-      handler_(static_cast<Handler&&>(handler))+      handler_(ASIO_MOVE_CAST(Handler)(handler))   {   } +#if defined(ASIO_HAS_MOVE)   wrapped_handler(const wrapped_handler& other)     : dispatcher_(other.dispatcher_),       handler_(other.handler_)@@ -87,85 +65,71 @@    wrapped_handler(wrapped_handler&& other)     : dispatcher_(other.dispatcher_),-      handler_(static_cast<Handler&&>(other.handler_))+      handler_(ASIO_MOVE_CAST(Handler)(other.handler_))   {   }--  executor_type get_executor() const noexcept-  {-    return wrapped_executor<Dispatcher>::get(dispatcher_);-  }+#endif // defined(ASIO_HAS_MOVE)    void operator()()   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(static_cast<Handler&&>(handler_));+    dispatcher_.dispatch(ASIO_MOVE_CAST(Handler)(handler_));   }    void operator()() const   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(handler_);+    dispatcher_.dispatch(handler_);   }    template <typename Arg1>   void operator()(const Arg1& arg1)   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(detail::bind_handler(handler_, arg1));+    dispatcher_.dispatch(detail::bind_handler(handler_, arg1));   }    template <typename Arg1>   void operator()(const Arg1& arg1) const   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(detail::bind_handler(handler_, arg1));+    dispatcher_.dispatch(detail::bind_handler(handler_, arg1));   }    template <typename Arg1, typename Arg2>   void operator()(const Arg1& arg1, const Arg2& arg2)   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(detail::bind_handler(handler_, arg1, arg2));+    dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2));   }    template <typename Arg1, typename Arg2>   void operator()(const Arg1& arg1, const Arg2& arg2) const   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(detail::bind_handler(handler_, arg1, arg2));+    dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2));   }    template <typename Arg1, typename Arg2, typename Arg3>   void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3)   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(detail::bind_handler(handler_, arg1, arg2, arg3));+    dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3));   }    template <typename Arg1, typename Arg2, typename Arg3>   void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) const   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(detail::bind_handler(handler_, arg1, arg2, arg3));+    dispatcher_.dispatch(detail::bind_handler(handler_, arg1, arg2, arg3));   }    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>   void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,       const Arg4& arg4)   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(-          detail::bind_handler(handler_, arg1, arg2, arg3, arg4));+    dispatcher_.dispatch(+        detail::bind_handler(handler_, arg1, arg2, arg3, arg4));   }    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>   void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,       const Arg4& arg4) const   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(-          detail::bind_handler(handler_, arg1, arg2, arg3, arg4));+    dispatcher_.dispatch(+        detail::bind_handler(handler_, arg1, arg2, arg3, arg4));   }    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,@@ -173,9 +137,8 @@   void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,       const Arg4& arg4, const Arg5& arg5)   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(-          detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));+    dispatcher_.dispatch(+        detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));   }    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,@@ -183,9 +146,8 @@   void operator()(const Arg1& arg1, const Arg2& arg2, const Arg3& arg3,       const Arg4& arg4, const Arg5& arg5) const   {-    detail::initiate_dispatch_with_executor<executor_type>(-        this->get_executor())(-          detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));+    dispatcher_.dispatch(+        detail::bind_handler(handler_, arg1, arg2, arg3, arg4, arg5));   }  //private:@@ -193,11 +155,168 @@   Handler handler_; }; +template <typename Handler, typename Context>+class rewrapped_handler+{+public:+  explicit rewrapped_handler(Handler& handler, const Context& context)+    : context_(context),+      handler_(ASIO_MOVE_CAST(Handler)(handler))+  {+  }++  explicit rewrapped_handler(const Handler& handler, const Context& context)+    : context_(context),+      handler_(handler)+  {+  }++#if defined(ASIO_HAS_MOVE)+  rewrapped_handler(const rewrapped_handler& other)+    : context_(other.context_),+      handler_(other.handler_)+  {+  }++  rewrapped_handler(rewrapped_handler&& other)+    : context_(ASIO_MOVE_CAST(Context)(other.context_)),+      handler_(ASIO_MOVE_CAST(Handler)(other.handler_))+  {+  }+#endif // defined(ASIO_HAS_MOVE)++  void operator()()+  {+    handler_();+  }++  void operator()() const+  {+    handler_();+  }++//private:+  Context context_;+  Handler handler_;+};+ template <typename Dispatcher, typename Handler, typename IsContinuation>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Dispatcher, typename Handler, typename IsContinuation>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Dispatcher, typename Handler, typename IsContinuation> inline bool asio_handler_is_continuation(     wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler) {   return IsContinuation()(this_handler->dispatcher_, this_handler->handler_);+}++template <typename Function, typename Dispatcher,+    typename Handler, typename IsContinuation>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)+{+  this_handler->dispatcher_.dispatch(+      rewrapped_handler<Function, Handler>(+        function, this_handler->handler_));+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Dispatcher,+    typename Handler, typename IsContinuation>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    wrapped_handler<Dispatcher, Handler, IsContinuation>* this_handler)+{+  this_handler->dispatcher_.dispatch(+      rewrapped_handler<Function, Handler>(+        function, this_handler->handler_));+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Context>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    rewrapped_handler<Handler, Context>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler, typename Context>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    rewrapped_handler<Handler, Context>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->context_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Dispatcher, typename Context>+inline bool asio_handler_is_continuation(+    rewrapped_handler<Dispatcher, Context>* this_handler)+{+  return asio_handler_cont_helpers::is_continuation(+      this_handler->context_);+}++template <typename Function, typename Handler, typename Context>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    rewrapped_handler<Handler, Context>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->context_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler, typename Context>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    rewrapped_handler<Handler, Context>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->context_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED) }  } // namespace detail
link/modules/asio-standalone/asio/include/asio/dispatch.hpp view
@@ -2,7 +2,7 @@ // dispatch.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -69,10 +69,11 @@  * @code void() @endcode  */ template <ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>-inline auto dispatch(NullaryToken&& token)-  -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) dispatch(+    ASIO_MOVE_ARG(NullaryToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<NullaryToken, void()>(-      declval<detail::initiate_dispatch>(), token))+        declval<detail::initiate_dispatch>(), token))) {   return async_initiate<NullaryToken, void()>(       detail::initiate_dispatch(), token);@@ -142,15 +143,17 @@  */ template <typename Executor,     ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken-      = default_completion_token_t<Executor>>-inline auto dispatch(const Executor& ex,-    NullaryToken&& token = default_completion_token_t<Executor>(),-    constraint_t<+      ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) dispatch(+    const Executor& ex,+    ASIO_MOVE_ARG(NullaryToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+    typename constraint<       execution::is_executor<Executor>::value || is_executor<Executor>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<NullaryToken, void()>(-      declval<detail::initiate_dispatch_with_executor<Executor>>(), token))+        declval<detail::initiate_dispatch_with_executor<Executor> >(), token))) {   return async_initiate<NullaryToken, void()>(       detail::initiate_dispatch_with_executor<Executor>(ex), token);@@ -172,17 +175,19 @@  */ template <typename ExecutionContext,     ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken-      = default_completion_token_t<typename ExecutionContext::executor_type>>-inline auto dispatch(ExecutionContext& ctx,-    NullaryToken&& token = default_completion_token_t<-      typename ExecutionContext::executor_type>(),-    constraint_t<-      is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)-  -> decltype(+      ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+        typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) dispatch(+    ExecutionContext& ctx,+    ASIO_MOVE_ARG(NullaryToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename ExecutionContext::executor_type),+    typename constraint<is_convertible<+      ExecutionContext&, execution_context&>::value>::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<NullaryToken, void()>(-      declval<detail::initiate_dispatch_with_executor<-        typename ExecutionContext::executor_type>>(), token))+        declval<detail::initiate_dispatch_with_executor<+          typename ExecutionContext::executor_type> >(), token))) {   return async_initiate<NullaryToken, void()>(       detail::initiate_dispatch_with_executor<
− link/modules/asio-standalone/asio/include/asio/disposition.hpp
@@ -1,282 +0,0 @@-//-// disposition.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_DISPOSITION_HPP-#define ASIO_DISPOSITION_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/detail/throw_exception.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/error_code.hpp"-#include "asio/system_error.hpp"-#include <exception>--#include "asio/detail/push_options.hpp"--namespace asio {--/// Traits type to adapt arbitrary error types as dispositions.-/**- * This type may be specialised for user-defined types, to allow them to be- * treated as a disposition by asio.- *- * The primary trait is not defined.- */-#if defined(GENERATING_DOCUMENTATION)-template <typename T>-struct disposition_traits-{-  /// Determine whether a disposition represents no error.-  static bool not_an_error(const T& d) noexcept;--  /// Throw an exception if the disposition represents an error.-  static void throw_exception(T d);--  /// Convert a disposition into an @c exception_ptr.-  static std::exception_ptr to_exception_ptr(T d) noexcept;-};-#else // defined(GENERATING_DOCUMENTATION)-template <typename T>-struct disposition_traits;-#endif // defined(GENERATING_DOCUMENTATION)--namespace detail {--template <typename T, typename = void, typename = void,-  typename = void, typename = void, typename = void, typename = void>-struct is_disposition_impl : false_type-{-};--template <typename T>-struct is_disposition_impl<T,-  enable_if_t<-    is_nothrow_default_constructible<T>::value-  >,-  enable_if_t<-    is_nothrow_move_constructible<T>::value-  >,-  enable_if_t<-    is_nothrow_move_assignable<T>::value-  >,-  enable_if_t<-    is_same<-      decltype(disposition_traits<T>::not_an_error(declval<const T&>())),-      bool-    >::value-  >,-  void_t<-    decltype(disposition_traits<T>::throw_exception(declval<T>()))-  >,-  enable_if_t<-    is_same<-      decltype(disposition_traits<T>::to_exception_ptr(declval<T>())),-      std::exception_ptr-    >::value-  >> : true_type-{-};--} // namespace detail--/// Trait used for testing whether a type satisfies the requirements of a-/// disposition.-/**- * To be a valid disposition, a type must be nothrow default-constructible,- * nothrow move-constructible, nothrow move-assignable, and there must be a- * specialisation of the disposition_traits template for the type that provides- * the following static member functions:- * @li @c not_an_error: Takes an argument of type <tt>const T&</tt> and returns- *     a @c bool.- * @li @c throw_exception: Takes an argument of type <tt>T</tt>. The- *     caller of this function must not pass a disposition value for which- *     @c not_an_error returns true. This function must not return.- * @li @c to_exception_ptr: Takes an argument of type <tt>T</tt> and returns a- *     value of type @c std::exception_ptr.- */-template <typename T>-struct is_disposition :-#if defined(GENERATING_DOCUMENTATION)-  integral_constant<bool, automatically_determined>-#else // defined(GENERATING_DOCUMENTATION)-  detail::is_disposition_impl<T>-#endif // defined(GENERATING_DOCUMENTATION)-{-};--#if defined(ASIO_HAS_VARIABLE_TEMPLATES)--template <typename T>-constexpr const bool is_disposition_v = is_disposition<T>::value;--#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)--#if defined(ASIO_HAS_CONCEPTS)--template <typename T>-ASIO_CONCEPT disposition = is_disposition<T>::value;--#define ASIO_DISPOSITION ::asio::disposition--#else // defined(ASIO_HAS_CONCEPTS)--#define ASIO_DISPOSITION typename--#endif // defined(ASIO_HAS_CONCEPTS)--/// Specialisation of @c disposition_traits for @c error_code.-template <>-struct disposition_traits<asio::error_code>-{-  static bool not_an_error(const asio::error_code& ec) noexcept-  {-    return !ec;-  }--  static void throw_exception(const asio::error_code& ec)-  {-    detail::throw_exception(asio::system_error(ec));-  }--  static std::exception_ptr to_exception_ptr(-      const asio::error_code& ec) noexcept-  {-    return ec-      ? std::make_exception_ptr(asio::system_error(ec))-      : nullptr;-  }-};--/// Specialisation of @c disposition_traits for @c std::exception_ptr.-template <>-struct disposition_traits<std::exception_ptr>-{-  static bool not_an_error(const std::exception_ptr& e) noexcept-  {-    return !e;-  }--  static void throw_exception(std::exception_ptr e)-  {-    std::rethrow_exception(static_cast<std::exception_ptr&&>(e));-  }--  static std::exception_ptr to_exception_ptr(std::exception_ptr e) noexcept-  {-    return e;-  }-};--/// A tag type used to indicate the absence of an error.-struct no_error_t-{-  /// Default constructor.-  constexpr no_error_t()-  {-  }--  /// Equality operator.-  friend constexpr bool operator==(-      const no_error_t&, const no_error_t&) noexcept-  {-    return true;-  }--  /// Inequality operator.-  friend constexpr bool operator!=(-      const no_error_t&, const no_error_t&) noexcept-  {-    return false;-  }--  /// Equality operator, returns true if the disposition does not contain an-  /// error.-  template <ASIO_DISPOSITION Disposition>-  friend constexpr constraint_t<is_disposition<Disposition>::value, bool>-  operator==(const no_error_t&, const Disposition& d) noexcept-  {-    return disposition_traits<Disposition>::not_an_error(d);-  }--  /// Equality operator, returns true if the disposition does not contain an-  /// error.-  template <ASIO_DISPOSITION Disposition>-  friend constexpr constraint_t<is_disposition<Disposition>::value, bool>-  operator==(const Disposition& d, const no_error_t&) noexcept-  {-    return disposition_traits<Disposition>::not_an_error(d);-  }--  /// Inequality operator, returns true if the disposition contains an error.-  template <ASIO_DISPOSITION Disposition>-  friend constexpr constraint_t<is_disposition<Disposition>::value, bool>-  operator!=(const no_error_t&, const Disposition& d) noexcept-  {-    return !disposition_traits<Disposition>::not_an_error(d);-  }--  /// Inequality operator, returns true if the disposition contains an error.-  template <ASIO_DISPOSITION Disposition>-  friend constexpr constraint_t<is_disposition<Disposition>::value, bool>-  operator!=(const Disposition& d, const no_error_t&) noexcept-  {-    return !disposition_traits<Disposition>::not_an_error(d);-  }-};--/// A special value used to indicate the absence of an error.-ASIO_INLINE_VARIABLE constexpr no_error_t no_error;--/// Specialisation of @c disposition_traits for @c no_error_t.-template <>-struct disposition_traits<no_error_t>-{-  static bool not_an_error(no_error_t) noexcept-  {-    return true;-  }--  static void throw_exception(no_error_t)-  {-  }--  static std::exception_ptr to_exception_ptr(no_error_t) noexcept-  {-    return std::exception_ptr();-  }-};--/// Helper function to throw an exception arising from a disposition.-template <typename Disposition>-inline void throw_exception(Disposition&& d,-    constraint_t<is_disposition<decay_t<Disposition>>::value> = 0)-{-  disposition_traits<decay_t<Disposition>>::throw_exception(-      static_cast<Disposition&&>(d));-}--/// Helper function to convert a disposition to an @c exception_ptr.-template <typename Disposition>-inline std::exception_ptr to_exception_ptr(Disposition&& d,-    constraint_t<is_disposition<decay_t<Disposition>>::value> = 0) noexcept-{-  return disposition_traits<decay_t<Disposition>>::to_exception_ptr(-      static_cast<Disposition&&>(d));-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_DISPOSITION_HPP
link/modules/asio-standalone/asio/include/asio/error.hpp view
@@ -2,7 +2,7 @@ // error.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -304,6 +304,7 @@ } // namespace error } // namespace asio +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std {  template<> struct is_error_code_enum<asio::error::basic_errors>@@ -327,6 +328,7 @@ };  } // namespace std+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)  namespace asio { namespace error {
link/modules/asio-standalone/asio/include/asio/error_code.hpp view
@@ -2,7 +2,7 @@ // error_code.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,17 +16,180 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <system_error> +#if defined(ASIO_HAS_STD_SYSTEM_ERROR)+# include <system_error>+#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)+# include <string>+# include "asio/detail/noncopyable.hpp"+# if !defined(ASIO_NO_IOSTREAM)+#  include <iosfwd>+# endif // !defined(ASIO_NO_IOSTREAM)+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)+ #include "asio/detail/push_options.hpp"  namespace asio { +#if defined(ASIO_HAS_STD_SYSTEM_ERROR)+ typedef std::error_category error_category;-typedef std::error_code error_code; +#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)++/// Base class for all error categories.+class error_category : private noncopyable+{+public:+  /// Destructor.+  virtual ~error_category()+  {+  }++  /// Returns a string naming the error gategory.+  virtual const char* name() const = 0;++  /// Returns a string describing the error denoted by @c value.+  virtual std::string message(int value) const = 0;++  /// Equality operator to compare two error categories.+  bool operator==(const error_category& rhs) const+  {+    return this == &rhs;+  }++  /// Inequality operator to compare two error categories.+  bool operator!=(const error_category& rhs) const+  {+    return !(*this == rhs);+  }+};++#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)+ /// Returns the error category used for the system errors produced by asio. extern ASIO_DECL const error_category& system_category();++#if defined(ASIO_HAS_STD_SYSTEM_ERROR)++typedef std::error_code error_code;++#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)++/// Class to represent an error code value.+class error_code+{+public:+  /// Default constructor.+  error_code()+    : value_(0),+      category_(&system_category())+  {+  }++  /// Construct with specific error code and category.+  error_code(int v, const error_category& c)+    : value_(v),+      category_(&c)+  {+  }++  /// Construct from an error code enum.+  template <typename ErrorEnum>+  error_code(ErrorEnum e)+  {+    *this = make_error_code(e);+  }++  /// Clear the error value to the default.+  void clear()+  {+    value_ = 0;+    category_ = &system_category();+  }++  /// Assign a new error value.+  void assign(int v, const error_category& c)+  {+    value_ = v;+    category_ = &c;+  }++  /// Get the error value.+  int value() const+  {+    return value_;+  }++  /// Get the error category.+  const error_category& category() const+  {+    return *category_;+  }++  /// Get the message associated with the error.+  std::string message() const+  {+    return category_->message(value_);+  }++  struct unspecified_bool_type_t+  {+  };++  typedef void (*unspecified_bool_type)(unspecified_bool_type_t);++  static void unspecified_bool_true(unspecified_bool_type_t) {}++  /// Operator returns non-null if there is a non-success error code.+  operator unspecified_bool_type() const+  {+    if (value_ == 0)+      return 0;+    else+      return &error_code::unspecified_bool_true;+  }++  /// Operator to test if the error represents success.+  bool operator!() const+  {+    return value_ == 0;+  }++  /// Equality operator to compare two error objects.+  friend bool operator==(const error_code& e1, const error_code& e2)+  {+    return e1.value_ == e2.value_ && e1.category_ == e2.category_;+  }++  /// Inequality operator to compare two error objects.+  friend bool operator!=(const error_code& e1, const error_code& e2)+  {+    return e1.value_ != e2.value_ || e1.category_ != e2.category_;+  }++private:+  // The value associated with the error code.+  int value_;++  // The category associated with the error code.+  const error_category* category_;+};++# if !defined(ASIO_NO_IOSTREAM)++/// Output an error code.+template <typename Elem, typename Traits>+std::basic_ostream<Elem, Traits>& operator<<(+    std::basic_ostream<Elem, Traits>& os, const error_code& ec)+{+  os << ec.category().name() << ':' << ec.value();+  return os;+}++# endif // !defined(ASIO_NO_IOSTREAM)++#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/execution.hpp view
@@ -2,7 +2,7 @@ // execution.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,14 +20,29 @@ #include "asio/execution/bad_executor.hpp" #include "asio/execution/blocking.hpp" #include "asio/execution/blocking_adaptation.hpp"+#include "asio/execution/bulk_execute.hpp"+#include "asio/execution/bulk_guarantee.hpp"+#include "asio/execution/connect.hpp" #include "asio/execution/context.hpp" #include "asio/execution/context_as.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/invocable_archetype.hpp" #include "asio/execution/mapping.hpp" #include "asio/execution/occupancy.hpp"+#include "asio/execution/operation_state.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/execution/prefer_only.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/receiver_invocation_error.hpp" #include "asio/execution/relationship.hpp"+#include "asio/execution/schedule.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"+#include "asio/execution/start.hpp"+#include "asio/execution/submit.hpp"  #endif // ASIO_EXECUTION_HPP
link/modules/asio-standalone/asio/include/asio/execution/allocator.hpp view
@@ -2,7 +2,7 @@ // execution/allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/traits/query_static_constexpr_member.hpp" #include "asio/traits/static_query.hpp"@@ -35,9 +37,10 @@ template <typename ProtoAllocator> struct allocator_t {-  /// The allocator_t property applies to executors.+  /// The allocator_t property applies to executors, senders, and schedulers.   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor_v<T>;+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;    /// The allocator_t property can be required.   static constexpr bool is_requirable = true;@@ -75,12 +78,32 @@ struct allocator_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);    template <typename T>   struct static_proxy@@ -89,17 +112,17 @@     struct type     {       template <typename P>-      static constexpr auto query(P&& p)+      static constexpr auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            conditional_t<true, T, P>::query(static_cast<P&&>(p))+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          conditional_t<true, T, P>::query(static_cast<P&&>(p))+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))         )       {-        return T::query(static_cast<P&&>(p));+        return T::query(ASIO_MOVE_CAST(P)(p));       }     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -115,19 +138,22 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(allocator_t::static_query<E>())>-  static constexpr const T static_query_v = allocator_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = allocator_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  constexpr ProtoAllocator value() const+  ASIO_CONSTEXPR ProtoAllocator value() const   {     return a_;   }@@ -135,7 +161,7 @@ private:   friend struct allocator_t<void>; -  explicit constexpr allocator_t(const ProtoAllocator& a)+  explicit ASIO_CONSTEXPR allocator_t(const ProtoAllocator& a)     : a_(a)   {   }@@ -154,14 +180,34 @@ struct allocator_t<void> { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); -  constexpr allocator_t()+  ASIO_CONSTEXPR allocator_t()   {   } @@ -172,17 +218,17 @@     struct type     {       template <typename P>-      static constexpr auto query(P&& p)+      static constexpr auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            conditional_t<true, T, P>::query(static_cast<P&&>(p))+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          conditional_t<true, T, P>::query(static_cast<P&&>(p))+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))         )       {-        return T::query(static_cast<P&&>(p));+        return T::query(ASIO_MOVE_CAST(P)(p));       }     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -198,20 +244,23 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(allocator_t::static_query<E>())>-  static constexpr const T static_query_v = allocator_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = allocator_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)    template <typename OtherProtoAllocator>-  constexpr allocator_t<OtherProtoAllocator> operator()(+  ASIO_CONSTEXPR allocator_t<OtherProtoAllocator> operator()(       const OtherProtoAllocator& a) const   {     return allocator_t<OtherProtoAllocator>(a);@@ -225,15 +274,44 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -ASIO_INLINE_VARIABLE constexpr allocator_t<void> allocator;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr allocator_t<void> allocator;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+template <typename T>+struct allocator_instance+{+  static allocator_t<T> instance;+}; +template <typename T>+allocator_t<T> allocator_instance<T>::instance;++namespace {+static const allocator_t<void>& allocator = allocator_instance<void>::instance;+} // namespace+#endif+ } // namespace execution  #if !defined(ASIO_HAS_VARIABLE_TEMPLATES)  template <typename T, typename ProtoAllocator>-struct is_applicable_property<T, execution::allocator_t<ProtoAllocator>>-  : integral_constant<bool, execution::is_executor<T>::value>+struct is_applicable_property<T, execution::allocator_t<ProtoAllocator> >+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { }; @@ -246,18 +324,18 @@  template <typename T, typename ProtoAllocator> struct static_query<T, execution::allocator_t<ProtoAllocator>,-  enable_if_t<+  typename enable_if<     execution::allocator_t<ProtoAllocator>::template       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::allocator_t<ProtoAllocator>::template     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::allocator_t<ProtoAllocator>::template       query_static_constexpr_member<T>::value();
link/modules/asio-standalone/asio/include/asio/execution/any_executor.hpp view
@@ -2,1924 +2,2654 @@ // execution/any_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_EXECUTION_ANY_EXECUTOR_HPP-#define ASIO_EXECUTION_ANY_EXECUTOR_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include <new>-#include <typeinfo>-#include "asio/detail/assert.hpp"-#include "asio/detail/atomic_count.hpp"-#include "asio/detail/cstddef.hpp"-#include "asio/detail/executor_function.hpp"-#include "asio/detail/memory.hpp"-#include "asio/detail/non_const_lvalue.hpp"-#include "asio/detail/scoped_ptr.hpp"-#include "asio/detail/type_traits.hpp"-#include "asio/detail/throw_exception.hpp"-#include "asio/execution/bad_executor.hpp"-#include "asio/execution/blocking.hpp"-#include "asio/execution/executor.hpp"-#include "asio/prefer.hpp"-#include "asio/query.hpp"-#include "asio/require.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--#if defined(GENERATING_DOCUMENTATION)--namespace execution {--/// Polymorphic executor wrapper.-template <typename... SupportableProperties>-class any_executor-{-public:-  /// Default constructor.-  any_executor() noexcept;--  /// Construct in an empty state. Equivalent effects to default constructor.-  any_executor(nullptr_t) noexcept;--  /// Copy constructor.-  any_executor(const any_executor& e) noexcept;--  /// Move constructor.-  any_executor(any_executor&& e) noexcept;--  /// Construct to point to the same target as another any_executor.-  template <class... OtherSupportableProperties>-    any_executor(any_executor<OtherSupportableProperties...> e);--  /// Construct to point to the same target as another any_executor.-  template <class... OtherSupportableProperties>-    any_executor(std::nothrow_t,-      any_executor<OtherSupportableProperties...> e) noexcept;--  /// Construct to point to the same target as another any_executor.-  any_executor(std::nothrow_t, const any_executor& e) noexcept;--  /// Construct to point to the same target as another any_executor.-  any_executor(std::nothrow_t, any_executor&& e) noexcept;--  /// Construct a polymorphic wrapper for the specified executor.-  template <typename Executor>-  any_executor(Executor e);--  /// Construct a polymorphic wrapper for the specified executor.-  template <typename Executor>-  any_executor(std::nothrow_t, Executor e) noexcept;--  /// Assignment operator.-  any_executor& operator=(const any_executor& e) noexcept;--  /// Move assignment operator.-  any_executor& operator=(any_executor&& e) noexcept;--  /// Assignment operator that sets the polymorphic wrapper to the empty state.-  any_executor& operator=(nullptr_t);--  /// Assignment operator to create a polymorphic wrapper for the specified-  /// executor.-  template <typename Executor>-  any_executor& operator=(Executor e);--  /// Destructor.-  ~any_executor();--  /// Swap targets with another polymorphic wrapper.-  void swap(any_executor& other) noexcept;--  /// Obtain a polymorphic wrapper with the specified property.-  /**-   * Do not call this function directly. It is intended for use with the-   * asio::require and asio::prefer customisation points.-   *-   * For example:-   * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;-   * auto ex2 = asio::require(ex, execution::blocking.possibly); @endcode-   */-  template <typename Property>-  any_executor require(Property) const;--  /// Obtain a polymorphic wrapper with the specified property.-  /**-   * Do not call this function directly. It is intended for use with the-   * asio::prefer customisation point.-   *-   * For example:-   * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;-   * auto ex2 = asio::prefer(ex, execution::blocking.possibly); @endcode-   */-  template <typename Property>-  any_executor prefer(Property) const;--  /// Obtain the value associated with the specified property.-  /**-   * Do not call this function directly. It is intended for use with the-   * asio::query customisation point.-   *-   * For example:-   * @code execution::any_executor<execution::occupancy_t> ex = ...;-   * size_t n = asio::query(ex, execution::occupancy); @endcode-   */-  template <typename Property>-  typename Property::polymorphic_query_result_type query(Property) const;--  /// Execute the function on the target executor.-  /**-   * Throws asio::bad_executor if the polymorphic wrapper has no target.-   */-  template <typename Function>-  void execute(Function&& f) const;--  /// Obtain the underlying execution context.-  /**-   * This function is provided for backward compatibility. It is automatically-   * defined when the @c SupportableProperties... list includes a property of-   * type <tt>execution::context_as<U></tt>, for some type <tt>U</tt>.-   */-  automatically_determined context() const;--  /// Determine whether the wrapper has a target executor.-  /**-   * @returns @c true if the polymorphic wrapper has a target executor,-   * otherwise false.-   */-  explicit operator bool() const noexcept;--  /// Get the type of the target executor.-  const type_info& target_type() const noexcept;--  /// Get a pointer to the target executor.-  template <typename Executor> Executor* target() noexcept;--  /// Get a pointer to the target executor.-  template <typename Executor> const Executor* target() const noexcept;-};--/// Equality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator==(const any_executor<SupportableProperties...>& a,-    const any_executor<SupportableProperties...>& b) noexcept;--/// Equality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator==(const any_executor<SupportableProperties...>& a,-    nullptr_t) noexcept;--/// Equality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator==(nullptr_t,-    const any_executor<SupportableProperties...>& b) noexcept;--/// Inequality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator!=(const any_executor<SupportableProperties...>& a,-    const any_executor<SupportableProperties...>& b) noexcept;--/// Inequality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator!=(const any_executor<SupportableProperties...>& a,-    nullptr_t) noexcept;--/// Inequality operator.-/**- * @relates any_executor- */-template <typename... SupportableProperties>-bool operator!=(nullptr_t,-    const any_executor<SupportableProperties...>& b) noexcept;--} // namespace execution--#else // defined(GENERATING_DOCUMENTATION)--namespace execution {--#if !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)-#define ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL--template <typename... SupportableProperties>-class any_executor;--#endif // !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)--template <typename U>-struct context_as_t;--namespace detail {--// Traits used to detect whether a property is requirable or preferable, taking-// into account that T::is_requirable or T::is_preferable may not not be well-// formed.--template <typename T, typename = void>-struct is_requirable : false_type {};--template <typename T>-struct is_requirable<T, enable_if_t<T::is_requirable>> : true_type {};--template <typename T, typename = void>-struct is_preferable : false_type {};--template <typename T>-struct is_preferable<T, enable_if_t<T::is_preferable>> : true_type {};--// Trait used to detect context_as property, for backward compatibility.--template <typename T>-struct is_context_as : false_type {};--template <typename U>-struct is_context_as<context_as_t<U>> : true_type {};--// Helper template to:-// - Check if a target can supply the supportable properties.-// - Find the first convertible-from-T property in the list.--template <std::size_t I, typename Props>-struct supportable_properties;--template <std::size_t I, typename Prop>-struct supportable_properties<I, void(Prop)>-{-  template <typename T>-  struct is_valid_target : integral_constant<bool,-      (-        is_requirable<Prop>::value-          ? can_require<T, Prop>::value-          : true-      )-      &&-      (-        is_preferable<Prop>::value-          ? can_prefer<T, Prop>::value-          : true-      )-      &&-      (-        !is_requirable<Prop>::value && !is_preferable<Prop>::value-          ? can_query<T, Prop>::value-          : true-      )-    >-  {-  };--  struct found-  {-    static constexpr bool value = true;-    typedef Prop type;-    typedef typename Prop::polymorphic_query_result_type query_result_type;-    static constexpr std::size_t index = I;-  };--  struct not_found-  {-    static constexpr bool value = false;-  };--  template <typename T>-  struct find_convertible_property :-      conditional_t<-        is_same<T, Prop>::value || is_convertible<T, Prop>::value,-        found,-        not_found-      > {};--  template <typename T>-  struct find_convertible_requirable_property :-      conditional_t<-        is_requirable<Prop>::value-          && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),-        found,-        not_found-      > {};--  template <typename T>-  struct find_convertible_preferable_property :-      conditional_t<-        is_preferable<Prop>::value-          && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),-        found,-        not_found-      > {};--  struct find_context_as_property :-      conditional_t<-        is_context_as<Prop>::value,-        found,-        not_found-      > {};-};--template <std::size_t I, typename Head, typename... Tail>-struct supportable_properties<I, void(Head, Tail...)>-{-  template <typename T>-  struct is_valid_target : integral_constant<bool,-      (-        supportable_properties<I,-          void(Head)>::template is_valid_target<T>::value-        &&-        supportable_properties<I + 1,-          void(Tail...)>::template is_valid_target<T>::value-      )-    >-  {-  };--  template <typename T>-  struct find_convertible_property :-      conditional_t<-        is_convertible<T, Head>::value,-        typename supportable_properties<I, void(Head)>::found,-        typename supportable_properties<I + 1,-            void(Tail...)>::template find_convertible_property<T>-      > {};--  template <typename T>-  struct find_convertible_requirable_property :-      conditional_t<-        is_requirable<Head>::value-          && is_convertible<T, Head>::value,-        typename supportable_properties<I, void(Head)>::found,-        typename supportable_properties<I + 1,-            void(Tail...)>::template find_convertible_requirable_property<T>-      > {};--  template <typename T>-  struct find_convertible_preferable_property :-      conditional_t<-        is_preferable<Head>::value-          && is_convertible<T, Head>::value,-        typename supportable_properties<I, void(Head)>::found,-        typename supportable_properties<I + 1,-            void(Tail...)>::template find_convertible_preferable_property<T>-      > {};--  struct find_context_as_property :-      conditional_t<-        is_context_as<Head>::value,-        typename supportable_properties<I, void(Head)>::found,-        typename supportable_properties<I + 1,-            void(Tail...)>::find_context_as_property-      > {};-};--template <typename T, typename Props>-struct is_valid_target_executor :-  conditional_t<-    is_executor<T>::value,-    typename supportable_properties<0, Props>::template is_valid_target<T>,-    false_type-  >-{-};--template <typename Props>-struct is_valid_target_executor<int, Props> : false_type-{-};--class shared_target_executor-{-public:-  template <typename E>-  shared_target_executor(E&& e, decay_t<E>*& target)-  {-    impl<decay_t<E>>* i =-      new impl<decay_t<E>>(static_cast<E&&>(e));-    target = &i->ex_;-    impl_ = i;-  }--  template <typename E>-  shared_target_executor(std::nothrow_t, E&& e, decay_t<E>*& target) noexcept-  {-    impl<decay_t<E>>* i =-      new (std::nothrow) impl<decay_t<E>>(static_cast<E&&>(e));-    target = i ? &i->ex_ : 0;-    impl_ = i;-  }--  shared_target_executor(const shared_target_executor& other) noexcept-    : impl_(other.impl_)-  {-    if (impl_)-      asio::detail::ref_count_up(impl_->ref_count_);-  }--  shared_target_executor(shared_target_executor&& other) noexcept-    : impl_(other.impl_)-  {-    other.impl_ = 0;-  }--  ~shared_target_executor()-  {-    if (impl_)-      if (asio::detail::ref_count_down(impl_->ref_count_))-        delete impl_;-  }--  void* get() const noexcept-  {-    return impl_ ? impl_->get() : 0;-  }--private:-  shared_target_executor& operator=(-      const shared_target_executor& other) = delete;--  shared_target_executor& operator=(-      shared_target_executor&& other) = delete;--  struct impl_base-  {-    impl_base() : ref_count_(1) {}-    virtual ~impl_base() {}-    virtual void* get() = 0;-    asio::detail::atomic_count ref_count_;-  };--  template <typename Executor>-  struct impl : impl_base-  {-    impl(Executor ex) : ex_(static_cast<Executor&&>(ex)) {}-    virtual void* get() { return &ex_; }-    Executor ex_;-  };--  impl_base* impl_;-};--class any_executor_base-{-public:-  any_executor_base() noexcept-    : object_fns_(0),-      target_(0),-      target_fns_(0)-  {-  }--  template <ASIO_EXECUTION_EXECUTOR Executor>-  any_executor_base(Executor ex, false_type)-    : target_fns_(target_fns_table<Executor>(-          any_executor_base::query_blocking(ex,-            can_query<const Executor&, const execution::blocking_t&>())-          == execution::blocking.always))-  {-    any_executor_base::construct_object(ex,-        integral_constant<bool,-          sizeof(Executor) <= sizeof(object_type)-            && alignment_of<Executor>::value <= alignment_of<object_type>::value-        >());-  }--  template <ASIO_EXECUTION_EXECUTOR Executor>-  any_executor_base(std::nothrow_t, Executor ex, false_type) noexcept-    : target_fns_(target_fns_table<Executor>(-          any_executor_base::query_blocking(ex,-            can_query<const Executor&, const execution::blocking_t&>())-          == execution::blocking.always))-  {-    any_executor_base::construct_object(std::nothrow, ex,-        integral_constant<bool,-          sizeof(Executor) <= sizeof(object_type)-            && alignment_of<Executor>::value <= alignment_of<object_type>::value-        >());-    if (target_ == 0)-    {-      object_fns_ = 0;-      target_fns_ = 0;-    }-  }--  template <ASIO_EXECUTION_EXECUTOR Executor>-  any_executor_base(Executor other, true_type)-    : object_fns_(object_fns_table<shared_target_executor>()),-      target_fns_(other.target_fns_)-  {-    Executor* p = 0;-    new (&object_) shared_target_executor(-        static_cast<Executor&&>(other), p);-    target_ = p->template target<void>();-  }--  template <ASIO_EXECUTION_EXECUTOR Executor>-  any_executor_base(std::nothrow_t,-      Executor other, true_type) noexcept-    : object_fns_(object_fns_table<shared_target_executor>()),-      target_fns_(other.target_fns_)-  {-    Executor* p = 0;-    new (&object_) shared_target_executor(-        std::nothrow, static_cast<Executor&&>(other), p);-    if (p)-      target_ = p->template target<void>();-    else-    {-      target_ = 0;-      object_fns_ = 0;-      target_fns_ = 0;-    }-  }--  any_executor_base(const any_executor_base& other) noexcept-  {-    if (!!other)-    {-      object_fns_ = other.object_fns_;-      target_fns_ = other.target_fns_;-      object_fns_->copy(*this, other);-    }-    else-    {-      object_fns_ = 0;-      target_ = 0;-      target_fns_ = 0;-    }-  }--  ~any_executor_base() noexcept-  {-    if (!!*this)-      object_fns_->destroy(*this);-  }--  any_executor_base& operator=(-      const any_executor_base& other) noexcept-  {-    if (this != &other)-    {-      if (!!*this)-        object_fns_->destroy(*this);-      if (!!other)-      {-        object_fns_ = other.object_fns_;-        target_fns_ = other.target_fns_;-        object_fns_->copy(*this, other);-      }-      else-      {-        object_fns_ = 0;-        target_ = 0;-        target_fns_ = 0;-      }-    }-    return *this;-  }--  any_executor_base& operator=(nullptr_t) noexcept-  {-    if (target_)-      object_fns_->destroy(*this);-    target_ = 0;-    object_fns_ = 0;-    target_fns_ = 0;-    return *this;-  }--  any_executor_base(any_executor_base&& other) noexcept-  {-    if (other.target_)-    {-      object_fns_ = other.object_fns_;-      target_fns_ = other.target_fns_;-      other.object_fns_ = 0;-      other.target_fns_ = 0;-      object_fns_->move(*this, other);-      other.target_ = 0;-    }-    else-    {-      object_fns_ = 0;-      target_ = 0;-      target_fns_ = 0;-    }-  }--  any_executor_base& operator=(-      any_executor_base&& other) noexcept-  {-    if (this != &other)-    {-      if (!!*this)-        object_fns_->destroy(*this);-      if (!!other)-      {-        object_fns_ = other.object_fns_;-        target_fns_ = other.target_fns_;-        other.object_fns_ = 0;-        other.target_fns_ = 0;-        object_fns_->move(*this, other);-        other.target_ = 0;-      }-      else-      {-        object_fns_ = 0;-        target_ = 0;-        target_fns_ = 0;-      }-    }-    return *this;-  }--  void swap(any_executor_base& other) noexcept-  {-    if (this != &other)-    {-      any_executor_base tmp(static_cast<any_executor_base&&>(other));-      other = static_cast<any_executor_base&&>(*this);-      *this = static_cast<any_executor_base&&>(tmp);-    }-  }--  template <typename F>-  void execute(F&& f) const-  {-    if (target_)-    {-      if (target_fns_->blocking_execute != 0)-      {-        asio::detail::non_const_lvalue<F> f2(f);-        target_fns_->blocking_execute(*this, function_view(f2.value));-      }-      else-      {-        target_fns_->execute(*this,-            function(static_cast<F&&>(f), std::allocator<void>()));-      }-    }-    else-    {-      bad_executor ex;-      asio::detail::throw_exception(ex);-    }-  }--  template <typename Executor>-  Executor* target()-  {-    return target_ && (is_same<Executor, void>::value-        || target_fns_->target_type() == target_type_ex<Executor>())-      ? static_cast<Executor*>(target_) : 0;-  }--  template <typename Executor>-  const Executor* target() const-  {-    return target_ && (is_same<Executor, void>::value-        || target_fns_->target_type() == target_type_ex<Executor>())-      ? static_cast<const Executor*>(target_) : 0;-  }--#if !defined(ASIO_NO_TYPEID)-  const std::type_info& target_type() const-  {-    return target_ ? target_fns_->target_type() : typeid(void);-  }-#else // !defined(ASIO_NO_TYPEID)-  const void* target_type() const-  {-    return target_ ? target_fns_->target_type() : 0;-  }-#endif // !defined(ASIO_NO_TYPEID)--  struct unspecified_bool_type_t {};-  typedef void (*unspecified_bool_type)(unspecified_bool_type_t);-  static void unspecified_bool_true(unspecified_bool_type_t) {}--  operator unspecified_bool_type() const noexcept-  {-    return target_ ? &any_executor_base::unspecified_bool_true : 0;-  }--  bool operator!() const noexcept-  {-    return target_ == 0;-  }--protected:-  bool equality_helper(const any_executor_base& other) const noexcept-  {-    if (target_ == other.target_)-      return true;-    if (target_ && !other.target_)-      return false;-    if (!target_ && other.target_)-      return false;-    if (target_fns_ != other.target_fns_)-      return false;-    return target_fns_->equal(*this, other);-  }--  template <typename Ex>-  Ex& object()-  {-    return *static_cast<Ex*>(static_cast<void*>(&object_));-  }--  template <typename Ex>-  const Ex& object() const-  {-    return *static_cast<const Ex*>(static_cast<const void*>(&object_));-  }--  struct object_fns-  {-    void (*destroy)(any_executor_base&);-    void (*copy)(any_executor_base&, const any_executor_base&);-    void (*move)(any_executor_base&, any_executor_base&);-    const void* (*target)(const any_executor_base&);-  };--  static void destroy_shared(any_executor_base& ex)-  {-    typedef shared_target_executor type;-    ex.object<type>().~type();-  }--  static void copy_shared(any_executor_base& ex1, const any_executor_base& ex2)-  {-    typedef shared_target_executor type;-    new (&ex1.object_) type(ex2.object<type>());-    ex1.target_ = ex2.target_;-  }--  static void move_shared(any_executor_base& ex1, any_executor_base& ex2)-  {-    typedef shared_target_executor type;-    new (&ex1.object_) type(static_cast<type&&>(ex2.object<type>()));-    ex1.target_ = ex2.target_;-    ex2.object<type>().~type();-  }--  static const void* target_shared(const any_executor_base& ex)-  {-    typedef shared_target_executor type;-    return ex.object<type>().get();-  }--  template <typename Obj>-  static const object_fns* object_fns_table(-      enable_if_t<-        is_same<Obj, shared_target_executor>::value-      >* = 0)-  {-    static const object_fns fns =-    {-      &any_executor_base::destroy_shared,-      &any_executor_base::copy_shared,-      &any_executor_base::move_shared,-      &any_executor_base::target_shared-    };-    return &fns;-  }--  template <typename Obj>-  static void destroy_object(any_executor_base& ex)-  {-    ex.object<Obj>().~Obj();-  }--  template <typename Obj>-  static void copy_object(any_executor_base& ex1, const any_executor_base& ex2)-  {-    new (&ex1.object_) Obj(ex2.object<Obj>());-    ex1.target_ = &ex1.object<Obj>();-  }--  template <typename Obj>-  static void move_object(any_executor_base& ex1, any_executor_base& ex2)-  {-    new (&ex1.object_) Obj(static_cast<Obj&&>(ex2.object<Obj>()));-    ex1.target_ = &ex1.object<Obj>();-    ex2.object<Obj>().~Obj();-  }--  template <typename Obj>-  static const void* target_object(const any_executor_base& ex)-  {-    return &ex.object<Obj>();-  }--  template <typename Obj>-  static const object_fns* object_fns_table(-      enable_if_t<-        !is_same<Obj, void>::value-          && !is_same<Obj, shared_target_executor>::value-      >* = 0)-  {-    static const object_fns fns =-    {-      &any_executor_base::destroy_object<Obj>,-      &any_executor_base::copy_object<Obj>,-      &any_executor_base::move_object<Obj>,-      &any_executor_base::target_object<Obj>-    };-    return &fns;-  }--  typedef asio::detail::executor_function function;-  typedef asio::detail::executor_function_view function_view;--  struct target_fns-  {-#if !defined(ASIO_NO_TYPEID)-    const std::type_info& (*target_type)();-#else // !defined(ASIO_NO_TYPEID)-    const void* (*target_type)();-#endif // !defined(ASIO_NO_TYPEID)-    bool (*equal)(const any_executor_base&, const any_executor_base&);-    void (*execute)(const any_executor_base&, function&&);-    void (*blocking_execute)(const any_executor_base&, function_view);-  };--#if !defined(ASIO_NO_TYPEID)-  template <typename Ex>-  static const std::type_info& target_type_ex()-  {-    return typeid(Ex);-  }-#else // !defined(ASIO_NO_TYPEID)-  template <typename Ex>-  static const void* target_type_ex()-  {-    static int unique_id;-    return &unique_id;-  }-#endif // !defined(ASIO_NO_TYPEID)--  template <typename Ex>-  static bool equal_ex(const any_executor_base& ex1,-      const any_executor_base& ex2)-  {-    const Ex* p1 = ex1.target<Ex>();-    const Ex* p2 = ex2.target<Ex>();-    ASIO_ASSUME(p1 != 0 && p2 != 0);-    return *p1 == *p2;-  }--  template <typename Ex>-  static void execute_ex(const any_executor_base& ex, function&& f)-  {-    const Ex* p = ex.target<Ex>();-    ASIO_ASSUME(p != 0);-    p->execute(static_cast<function&&>(f));-  }--  template <typename Ex>-  static void blocking_execute_ex(const any_executor_base& ex, function_view f)-  {-    const Ex* p = ex.target<Ex>();-    ASIO_ASSUME(p != 0);-    p->execute(f);-  }--  template <typename Ex>-  static const target_fns* target_fns_table(bool is_always_blocking,-      enable_if_t<-        !is_same<Ex, void>::value-      >* = 0)-  {-    static const target_fns fns_with_execute =-    {-      &any_executor_base::target_type_ex<Ex>,-      &any_executor_base::equal_ex<Ex>,-      &any_executor_base::execute_ex<Ex>,-      0-    };--    static const target_fns fns_with_blocking_execute =-    {-      &any_executor_base::target_type_ex<Ex>,-      &any_executor_base::equal_ex<Ex>,-      0,-      &any_executor_base::blocking_execute_ex<Ex>-    };--    return is_always_blocking ? &fns_with_blocking_execute : &fns_with_execute;-  }--#if defined(ASIO_MSVC)-# pragma warning (push)-# pragma warning (disable:4702)-#endif // defined(ASIO_MSVC)--  static void query_fn_void(void*, const void*, const void*)-  {-    bad_executor ex;-    asio::detail::throw_exception(ex);-  }--  template <typename Ex, class Prop>-  static void query_fn_non_void(void*, const void* ex, const void* prop,-      enable_if_t<-        asio::can_query<const Ex&, const Prop&>::value-          && is_same<typename Prop::polymorphic_query_result_type, void>::value-      >*)-  {-    asio::query(*static_cast<const Ex*>(ex),-        *static_cast<const Prop*>(prop));-  }--  template <typename Ex, class Prop>-  static void query_fn_non_void(void*, const void*, const void*,-      enable_if_t<-        !asio::can_query<const Ex&, const Prop&>::value-          && is_same<typename Prop::polymorphic_query_result_type, void>::value-      >*)-  {-  }--  template <typename Ex, class Prop>-  static void query_fn_non_void(void* result, const void* ex, const void* prop,-      enable_if_t<-        asio::can_query<const Ex&, const Prop&>::value-          && !is_same<typename Prop::polymorphic_query_result_type, void>::value-          && is_reference<typename Prop::polymorphic_query_result_type>::value-      >*)-  {-    *static_cast<remove_reference_t<-      typename Prop::polymorphic_query_result_type>**>(result)-        = &static_cast<typename Prop::polymorphic_query_result_type>(-            asio::query(*static_cast<const Ex*>(ex),-              *static_cast<const Prop*>(prop)));-  }--  template <typename Ex, class Prop>-  static void query_fn_non_void(void*, const void*, const void*,-      enable_if_t<-        !asio::can_query<const Ex&, const Prop&>::value-          && !is_same<typename Prop::polymorphic_query_result_type, void>::value-          && is_reference<typename Prop::polymorphic_query_result_type>::value-      >*)-  {-    std::terminate(); // Combination should not be possible.-  }--  template <typename Ex, class Prop>-  static void query_fn_non_void(void* result, const void* ex, const void* prop,-      enable_if_t<-        asio::can_query<const Ex&, const Prop&>::value-          && !is_same<typename Prop::polymorphic_query_result_type, void>::value-          && is_scalar<typename Prop::polymorphic_query_result_type>::value-      >*)-  {-    *static_cast<typename Prop::polymorphic_query_result_type*>(result)-      = static_cast<typename Prop::polymorphic_query_result_type>(-          asio::query(*static_cast<const Ex*>(ex),-            *static_cast<const Prop*>(prop)));-  }--  template <typename Ex, class Prop>-  static void query_fn_non_void(void* result, const void*, const void*,-      enable_if_t<-        !asio::can_query<const Ex&, const Prop&>::value-          && !is_same<typename Prop::polymorphic_query_result_type, void>::value-          && is_scalar<typename Prop::polymorphic_query_result_type>::value-      >*)-  {-    *static_cast<typename Prop::polymorphic_query_result_type*>(result)-      = typename Prop::polymorphic_query_result_type();-  }--  template <typename Ex, class Prop>-  static void query_fn_non_void(void* result, const void* ex, const void* prop,-      enable_if_t<-        asio::can_query<const Ex&, const Prop&>::value-          && !is_same<typename Prop::polymorphic_query_result_type, void>::value-          && !is_reference<typename Prop::polymorphic_query_result_type>::value-          && !is_scalar<typename Prop::polymorphic_query_result_type>::value-      >*)-  {-    *static_cast<typename Prop::polymorphic_query_result_type**>(result)-      = new typename Prop::polymorphic_query_result_type(-          asio::query(*static_cast<const Ex*>(ex),-            *static_cast<const Prop*>(prop)));-  }--  template <typename Ex, class Prop>-  static void query_fn_non_void(void* result, const void*, const void*, ...)-  {-    *static_cast<typename Prop::polymorphic_query_result_type**>(result)-      = new typename Prop::polymorphic_query_result_type();-  }--  template <typename Ex, class Prop>-  static void query_fn_impl(void* result, const void* ex, const void* prop,-      enable_if_t<-        is_same<Ex, void>::value-      >*)-  {-    query_fn_void(result, ex, prop);-  }--  template <typename Ex, class Prop>-  static void query_fn_impl(void* result, const void* ex, const void* prop,-      enable_if_t<-        !is_same<Ex, void>::value-      >*)-  {-    query_fn_non_void<Ex, Prop>(result, ex, prop, 0);-  }--  template <typename Ex, class Prop>-  static void query_fn(void* result, const void* ex, const void* prop)-  {-    query_fn_impl<Ex, Prop>(result, ex, prop, 0);-  }--  template <typename Poly, typename Ex, class Prop>-  static Poly require_fn_impl(const void*, const void*,-      enable_if_t<-        is_same<Ex, void>::value-      >*)-  {-    bad_executor ex;-    asio::detail::throw_exception(ex);-    return Poly();-  }--  template <typename Poly, typename Ex, class Prop>-  static Poly require_fn_impl(const void* ex, const void* prop,-      enable_if_t<-        !is_same<Ex, void>::value && Prop::is_requirable-      >*)-  {-    return asio::require(*static_cast<const Ex*>(ex),-        *static_cast<const Prop*>(prop));-  }--  template <typename Poly, typename Ex, class Prop>-  static Poly require_fn_impl(const void*, const void*, ...)-  {-    return Poly();-  }--  template <typename Poly, typename Ex, class Prop>-  static Poly require_fn(const void* ex, const void* prop)-  {-    return require_fn_impl<Poly, Ex, Prop>(ex, prop, 0);-  }--  template <typename Poly, typename Ex, class Prop>-  static Poly prefer_fn_impl(const void*, const void*,-      enable_if_t<-        is_same<Ex, void>::value-      >*)-  {-    bad_executor ex;-    asio::detail::throw_exception(ex);-    return Poly();-  }--  template <typename Poly, typename Ex, class Prop>-  static Poly prefer_fn_impl(const void* ex, const void* prop,-      enable_if_t<-        !is_same<Ex, void>::value && Prop::is_preferable-      >*)-  {-    return asio::prefer(*static_cast<const Ex*>(ex),-        *static_cast<const Prop*>(prop));-  }--  template <typename Poly, typename Ex, class Prop>-  static Poly prefer_fn_impl(const void*, const void*, ...)-  {-    return Poly();-  }--  template <typename Poly, typename Ex, class Prop>-  static Poly prefer_fn(const void* ex, const void* prop)-  {-    return prefer_fn_impl<Poly, Ex, Prop>(ex, prop, 0);-  }--  template <typename Poly>-  struct prop_fns-  {-    void (*query)(void*, const void*, const void*);-    Poly (*require)(const void*, const void*);-    Poly (*prefer)(const void*, const void*);-  };--#if defined(ASIO_MSVC)-# pragma warning (pop)-#endif // defined(ASIO_MSVC)--private:-  template <typename Executor>-  static execution::blocking_t query_blocking(const Executor& ex, true_type)-  {-    return asio::query(ex, execution::blocking);-  }--  template <typename Executor>-  static execution::blocking_t query_blocking(const Executor&, false_type)-  {-    return execution::blocking_t();-  }--  template <typename Executor>-  void construct_object(Executor& ex, true_type)-  {-    object_fns_ = object_fns_table<Executor>();-    target_ = new (&object_) Executor(static_cast<Executor&&>(ex));-  }--  template <typename Executor>-  void construct_object(Executor& ex, false_type)-  {-    object_fns_ = object_fns_table<shared_target_executor>();-    Executor* p = 0;-    new (&object_) shared_target_executor(-        static_cast<Executor&&>(ex), p);-    target_ = p;-  }--  template <typename Executor>-  void construct_object(std::nothrow_t,-      Executor& ex, true_type) noexcept-  {-    object_fns_ = object_fns_table<Executor>();-    target_ = new (&object_) Executor(static_cast<Executor&&>(ex));-  }--  template <typename Executor>-  void construct_object(std::nothrow_t,-      Executor& ex, false_type) noexcept-  {-    object_fns_ = object_fns_table<shared_target_executor>();-    Executor* p = 0;-    new (&object_) shared_target_executor(-        std::nothrow, static_cast<Executor&&>(ex), p);-    target_ = p;-  }--/*private:*/public:-//  template <typename...> friend class any_executor;--  typedef aligned_storage<-      sizeof(asio::detail::shared_ptr<void>) + sizeof(void*),-      alignment_of<asio::detail::shared_ptr<void>>::value-    >::type object_type;--  object_type object_;-  const object_fns* object_fns_;-  void* target_;-  const target_fns* target_fns_;-};--template <typename Derived, typename Property, typename = void>-struct any_executor_context-{-};--#if !defined(ASIO_NO_TS_EXECUTORS)--template <typename Derived, typename Property>-struct any_executor_context<Derived, Property, enable_if_t<Property::value>>-{-  typename Property::query_result_type context() const-  {-    return static_cast<const Derived*>(this)->query(typename Property::type());-  }-};--#endif // !defined(ASIO_NO_TS_EXECUTORS)--} // namespace detail--template <>-class any_executor<> : public detail::any_executor_base-{-public:-  any_executor() noexcept-    : detail::any_executor_base()-  {-  }--  any_executor(nullptr_t) noexcept-    : detail::any_executor_base()-  {-  }--  template <typename Executor>-  any_executor(Executor ex,-      enable_if_t<-        conditional_t<-          !is_same<Executor, any_executor>::value-            && !is_base_of<detail::any_executor_base, Executor>::value,-          is_executor<Executor>,-          false_type-        >::value-      >* = 0)-    : detail::any_executor_base(-        static_cast<Executor&&>(ex), false_type())-  {-  }--  template <typename Executor>-  any_executor(std::nothrow_t, Executor ex,-      enable_if_t<-        conditional_t<-          !is_same<Executor, any_executor>::value-            && !is_base_of<detail::any_executor_base, Executor>::value,-          is_executor<Executor>,-          false_type-        >::value-      >* = 0) noexcept-    : detail::any_executor_base(std::nothrow,-        static_cast<Executor&&>(ex), false_type())-  {-  }--  template <typename... OtherSupportableProperties>-  any_executor(any_executor<OtherSupportableProperties...> other)-    : detail::any_executor_base(-        static_cast<const detail::any_executor_base&>(other))-  {-  }--  template <typename... OtherSupportableProperties>-  any_executor(std::nothrow_t,-      any_executor<OtherSupportableProperties...> other) noexcept-    : detail::any_executor_base(-        static_cast<const detail::any_executor_base&>(other))-  {-  }--  any_executor(const any_executor& other) noexcept-    : detail::any_executor_base(-        static_cast<const detail::any_executor_base&>(other))-  {-  }--  any_executor(std::nothrow_t, const any_executor& other) noexcept-    : detail::any_executor_base(-        static_cast<const detail::any_executor_base&>(other))-  {-  }--  any_executor& operator=(const any_executor& other) noexcept-  {-    if (this != &other)-    {-      detail::any_executor_base::operator=(-          static_cast<const detail::any_executor_base&>(other));-    }-    return *this;-  }--  any_executor& operator=(nullptr_t p) noexcept-  {-    detail::any_executor_base::operator=(p);-    return *this;-  }--  any_executor(any_executor&& other) noexcept-    : detail::any_executor_base(-        static_cast<any_executor_base&&>(-          static_cast<any_executor_base&>(other)))-  {-  }--  any_executor(std::nothrow_t, any_executor&& other) noexcept-    : detail::any_executor_base(-        static_cast<any_executor_base&&>(-          static_cast<any_executor_base&>(other)))-  {-  }--  any_executor& operator=(any_executor&& other) noexcept-  {-    if (this != &other)-    {-      detail::any_executor_base::operator=(-          static_cast<detail::any_executor_base&&>(-            static_cast<detail::any_executor_base&>(other)));-    }-    return *this;-  }--  void swap(any_executor& other) noexcept-  {-    detail::any_executor_base::swap(-        static_cast<detail::any_executor_base&>(other));-  }--  using detail::any_executor_base::execute;-  using detail::any_executor_base::target;-  using detail::any_executor_base::target_type;-  using detail::any_executor_base::operator unspecified_bool_type;-  using detail::any_executor_base::operator!;--  bool equality_helper(const any_executor& other) const noexcept-  {-    return any_executor_base::equality_helper(other);-  }--  template <typename AnyExecutor1, typename AnyExecutor2>-  friend enable_if_t<-    is_base_of<any_executor, AnyExecutor1>::value-      || is_base_of<any_executor, AnyExecutor2>::value,-    bool-  > operator==(const AnyExecutor1& a,-      const AnyExecutor2& b) noexcept-  {-    return static_cast<const any_executor&>(a).equality_helper(b);-  }--  template <typename AnyExecutor>-  friend enable_if_t<-    is_same<AnyExecutor, any_executor>::value,-    bool-  > operator==(const AnyExecutor& a, nullptr_t) noexcept-  {-    return !a;-  }--  template <typename AnyExecutor>-  friend enable_if_t<-    is_same<AnyExecutor, any_executor>::value,-    bool-  > operator==(nullptr_t, const AnyExecutor& b) noexcept-  {-    return !b;-  }--  template <typename AnyExecutor1, typename AnyExecutor2>-  friend enable_if_t<-    is_base_of<any_executor, AnyExecutor1>::value-      || is_base_of<any_executor, AnyExecutor2>::value,-    bool-  > operator!=(const AnyExecutor1& a,-      const AnyExecutor2& b) noexcept-  {-    return !static_cast<const any_executor&>(a).equality_helper(b);-  }--  template <typename AnyExecutor>-  friend enable_if_t<-    is_same<AnyExecutor, any_executor>::value,-    bool-  > operator!=(const AnyExecutor& a, nullptr_t) noexcept-  {-    return !!a;-  }--  template <typename AnyExecutor>-  friend enable_if_t<-    is_same<AnyExecutor, any_executor>::value,-    bool-  > operator!=(nullptr_t, const AnyExecutor& b) noexcept-  {-    return !!b;-  }-};--inline void swap(any_executor<>& a, any_executor<>& b) noexcept-{-  return a.swap(b);-}--template <typename... SupportableProperties>-class any_executor :-  public detail::any_executor_base,-  public detail::any_executor_context<-    any_executor<SupportableProperties...>,-      typename detail::supportable_properties<-        0, void(SupportableProperties...)>::find_context_as_property>-{-public:-  any_executor() noexcept-    : detail::any_executor_base(),-      prop_fns_(prop_fns_table<void>())-  {-  }--  any_executor(nullptr_t) noexcept-    : detail::any_executor_base(),-      prop_fns_(prop_fns_table<void>())-  {-  }--  template <typename Executor>-  any_executor(Executor ex,-      enable_if_t<-        conditional_t<-          !is_same<Executor, any_executor>::value-            && !is_base_of<detail::any_executor_base, Executor>::value,-          detail::is_valid_target_executor<-            Executor, void(SupportableProperties...)>,-          false_type-        >::value-      >* = 0)-    : detail::any_executor_base(-        static_cast<Executor&&>(ex), false_type()),-      prop_fns_(prop_fns_table<Executor>())-  {-  }--  template <typename Executor>-  any_executor(std::nothrow_t, Executor ex,-      enable_if_t<-        conditional_t<-          !is_same<Executor, any_executor>::value-            && !is_base_of<detail::any_executor_base, Executor>::value,-          detail::is_valid_target_executor<-            Executor, void(SupportableProperties...)>,-          false_type-        >::value-      >* = 0) noexcept-    : detail::any_executor_base(std::nothrow,-        static_cast<Executor&&>(ex), false_type()),-      prop_fns_(prop_fns_table<Executor>())-  {-    if (this->template target<void>() == 0)-      prop_fns_ = prop_fns_table<void>();-  }--  template <typename... OtherSupportableProperties>-  any_executor(any_executor<OtherSupportableProperties...> other,-      enable_if_t<-        conditional_t<-          !is_same<-            any_executor<OtherSupportableProperties...>,-            any_executor-          >::value,-          typename detail::supportable_properties<-            0, void(SupportableProperties...)>::template is_valid_target<-              any_executor<OtherSupportableProperties...>>,-          false_type-        >::value-      >* = 0)-    : detail::any_executor_base(-        static_cast<any_executor<OtherSupportableProperties...>&&>(other),-        true_type()),-      prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...>>())-  {-  }--  template <typename... OtherSupportableProperties>-  any_executor(std::nothrow_t,-      any_executor<OtherSupportableProperties...> other,-      enable_if_t<-        conditional_t<-          !is_same<-            any_executor<OtherSupportableProperties...>,-            any_executor-          >::value,-          typename detail::supportable_properties<-            0, void(SupportableProperties...)>::template is_valid_target<-              any_executor<OtherSupportableProperties...>>,-          false_type-        >::value-      >* = 0) noexcept-    : detail::any_executor_base(std::nothrow,-        static_cast<any_executor<OtherSupportableProperties...>&&>(other),-        true_type()),-      prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...>>())-  {-    if (this->template target<void>() == 0)-      prop_fns_ = prop_fns_table<void>();-  }--  any_executor(const any_executor& other) noexcept-    : detail::any_executor_base(-        static_cast<const detail::any_executor_base&>(other)),-      prop_fns_(other.prop_fns_)-  {-  }--  any_executor(std::nothrow_t, const any_executor& other) noexcept-    : detail::any_executor_base(-        static_cast<const detail::any_executor_base&>(other)),-      prop_fns_(other.prop_fns_)-  {-  }--  any_executor& operator=(const any_executor& other) noexcept-  {-    if (this != &other)-    {-      prop_fns_ = other.prop_fns_;-      detail::any_executor_base::operator=(-          static_cast<const detail::any_executor_base&>(other));-    }-    return *this;-  }--  any_executor& operator=(nullptr_t p) noexcept-  {-    prop_fns_ = prop_fns_table<void>();-    detail::any_executor_base::operator=(p);-    return *this;-  }--  any_executor(any_executor&& other) noexcept-    : detail::any_executor_base(-        static_cast<any_executor_base&&>(-          static_cast<any_executor_base&>(other))),-      prop_fns_(other.prop_fns_)-  {-    other.prop_fns_ = prop_fns_table<void>();-  }--  any_executor(std::nothrow_t, any_executor&& other) noexcept-    : detail::any_executor_base(-        static_cast<any_executor_base&&>(-          static_cast<any_executor_base&>(other))),-      prop_fns_(other.prop_fns_)-  {-    other.prop_fns_ = prop_fns_table<void>();-  }--  any_executor& operator=(any_executor&& other) noexcept-  {-    if (this != &other)-    {-      prop_fns_ = other.prop_fns_;-      detail::any_executor_base::operator=(-          static_cast<detail::any_executor_base&&>(-            static_cast<detail::any_executor_base&>(other)));-    }-    return *this;-  }--  void swap(any_executor& other) noexcept-  {-    if (this != &other)-    {-      detail::any_executor_base::swap(-          static_cast<detail::any_executor_base&>(other));-      const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_;-      other.prop_fns_ = prop_fns_;-      prop_fns_ = tmp_prop_fns;-    }-  }--  using detail::any_executor_base::execute;-  using detail::any_executor_base::target;-  using detail::any_executor_base::target_type;-  using detail::any_executor_base::operator unspecified_bool_type;-  using detail::any_executor_base::operator!;--  bool equality_helper(const any_executor& other) const noexcept-  {-    return any_executor_base::equality_helper(other);-  }--  template <typename AnyExecutor1, typename AnyExecutor2>-  friend enable_if_t<-    is_base_of<any_executor, AnyExecutor1>::value-      || is_base_of<any_executor, AnyExecutor2>::value,-    bool-  > operator==(const AnyExecutor1& a,-      const AnyExecutor2& b) noexcept-  {-    return static_cast<const any_executor&>(a).equality_helper(b);-  }--  template <typename AnyExecutor>-  friend enable_if_t<-    is_same<AnyExecutor, any_executor>::value,-    bool-  > operator==(const AnyExecutor& a, nullptr_t) noexcept-  {-    return !a;-  }--  template <typename AnyExecutor>-  friend enable_if_t<-    is_same<AnyExecutor, any_executor>::value,-    bool-  > operator==(nullptr_t, const AnyExecutor& b) noexcept-  {-    return !b;-  }--  template <typename AnyExecutor1, typename AnyExecutor2>-  friend enable_if_t<-    is_base_of<any_executor, AnyExecutor1>::value-      || is_base_of<any_executor, AnyExecutor2>::value,-    bool-  > operator!=(const AnyExecutor1& a,-      const AnyExecutor2& b) noexcept-  {-    return !static_cast<const any_executor&>(a).equality_helper(b);-  }--  template <typename AnyExecutor>-  friend enable_if_t<-    is_same<AnyExecutor, any_executor>::value,-    bool-  > operator!=(const AnyExecutor& a, nullptr_t) noexcept-  {-    return !!a;-  }--  template <typename AnyExecutor>-  friend enable_if_t<-    is_same<AnyExecutor, any_executor>::value,-    bool-  > operator!=(nullptr_t, const AnyExecutor& b) noexcept-  {-    return !!b;-  }--  template <typename T>-  struct find_convertible_property :-      detail::supportable_properties<-        0, void(SupportableProperties...)>::template-          find_convertible_property<T> {};--  template <typename Property>-  void query(const Property& p,-      enable_if_t<-        is_same<-          typename find_convertible_property<Property>::query_result_type,-          void-        >::value-      >* = 0) const-  {-    if (!target_)-    {-      bad_executor ex;-      asio::detail::throw_exception(ex);-    }-    typedef find_convertible_property<Property> found;-    prop_fns_[found::index].query(0, object_fns_->target(*this),-        &static_cast<const typename found::type&>(p));-  }--  template <typename Property>-  typename find_convertible_property<Property>::query_result_type-  query(const Property& p,-      enable_if_t<-        !is_same<-          typename find_convertible_property<Property>::query_result_type,-          void-        >::value-        &&-        is_reference<-          typename find_convertible_property<Property>::query_result_type-        >::value-      >* = 0) const-  {-    if (!target_)-    {-      bad_executor ex;-      asio::detail::throw_exception(ex);-    }-    typedef find_convertible_property<Property> found;-    remove_reference_t<typename found::query_result_type>* result = 0;-    prop_fns_[found::index].query(&result, object_fns_->target(*this),-        &static_cast<const typename found::type&>(p));-    return *result;-  }--  template <typename Property>-  typename find_convertible_property<Property>::query_result_type-  query(const Property& p,-      enable_if_t<-        !is_same<-          typename find_convertible_property<Property>::query_result_type,-          void-        >::value-        &&-        is_scalar<-          typename find_convertible_property<Property>::query_result_type-        >::value-      >* = 0) const-  {-    if (!target_)-    {-      bad_executor ex;-      asio::detail::throw_exception(ex);-    }-    typedef find_convertible_property<Property> found;-    typename found::query_result_type result;-    prop_fns_[found::index].query(&result, object_fns_->target(*this),-        &static_cast<const typename found::type&>(p));-    return result;-  }--  template <typename Property>-  typename find_convertible_property<Property>::query_result_type-  query(const Property& p,-      enable_if_t<-        !is_same<-          typename find_convertible_property<Property>::query_result_type,-          void-        >::value-        &&-        !is_reference<-          typename find_convertible_property<Property>::query_result_type-        >::value-        &&-        !is_scalar<-          typename find_convertible_property<Property>::query_result_type-        >::value-      >* = 0) const-  {-    if (!target_)-    {-      bad_executor ex;-      asio::detail::throw_exception(ex);-    }-    typedef find_convertible_property<Property> found;-    typename found::query_result_type* result;-    prop_fns_[found::index].query(&result, object_fns_->target(*this),-        &static_cast<const typename found::type&>(p));-    return *asio::detail::scoped_ptr<-      typename found::query_result_type>(result);-  }--  template <typename T>-  struct find_convertible_requirable_property :-      detail::supportable_properties<-        0, void(SupportableProperties...)>::template-          find_convertible_requirable_property<T> {};--  template <typename Property>-  any_executor require(const Property& p,-      enable_if_t<-        find_convertible_requirable_property<Property>::value-      >* = 0) const-  {-    if (!target_)-    {-      bad_executor ex;-      asio::detail::throw_exception(ex);-    }-    typedef find_convertible_requirable_property<Property> found;-    return prop_fns_[found::index].require(object_fns_->target(*this),-        &static_cast<const typename found::type&>(p));-  }--  template <typename T>-  struct find_convertible_preferable_property :-      detail::supportable_properties<-        0, void(SupportableProperties...)>::template-          find_convertible_preferable_property<T> {};--  template <typename Property>-  any_executor prefer(const Property& p,-      enable_if_t<-        find_convertible_preferable_property<Property>::value-      >* = 0) const-  {-    if (!target_)-    {-      bad_executor ex;-      asio::detail::throw_exception(ex);-    }-    typedef find_convertible_preferable_property<Property> found;-    return prop_fns_[found::index].prefer(object_fns_->target(*this),-        &static_cast<const typename found::type&>(p));-  }--//private:-  template <typename Ex>-  static const prop_fns<any_executor>* prop_fns_table()-  {-    static const prop_fns<any_executor> fns[] =-    {-      {-        &detail::any_executor_base::query_fn<-            Ex, SupportableProperties>,-        &detail::any_executor_base::require_fn<-            any_executor, Ex, SupportableProperties>,-        &detail::any_executor_base::prefer_fn<-            any_executor, Ex, SupportableProperties>-      }...-    };-    return fns;-  }--  const prop_fns<any_executor>* prop_fns_;-};--template <typename... SupportableProperties>-inline void swap(any_executor<SupportableProperties...>& a,-    any_executor<SupportableProperties...>& b) noexcept-{-  return a.swap(b);-}--} // namespace execution-namespace traits {--#if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)--template <typename... SupportableProperties>-struct equality_comparable<execution::any_executor<SupportableProperties...>>-{-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;-};--#endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)--#if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)--template <typename F, typename... SupportableProperties>-struct execute_member<execution::any_executor<SupportableProperties...>, F>-{-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;-  typedef void result_type;-};--#endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)--#if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)--template <typename Prop, typename... SupportableProperties>-struct query_member<-    execution::any_executor<SupportableProperties...>, Prop,-    enable_if_t<-      execution::detail::supportable_properties<-        0, void(SupportableProperties...)>::template-          find_convertible_property<Prop>::value-    >>-{-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;-  typedef typename execution::detail::supportable_properties<-      0, void(SupportableProperties...)>::template-        find_convertible_property<Prop>::query_result_type result_type;-};--#endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)--#if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)--template <typename Prop, typename... SupportableProperties>-struct require_member<-    execution::any_executor<SupportableProperties...>, Prop,-    enable_if_t<-      execution::detail::supportable_properties<-        0, void(SupportableProperties...)>::template-          find_convertible_requirable_property<Prop>::value-    >>-{-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;-  typedef execution::any_executor<SupportableProperties...> result_type;-};--#endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)--#if !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)--template <typename Prop, typename... SupportableProperties>-struct prefer_member<-    execution::any_executor<SupportableProperties...>, Prop,-    enable_if_t<-      execution::detail::supportable_properties<-        0, void(SupportableProperties...)>::template-          find_convertible_preferable_property<Prop>::value-    >>-{-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;-  typedef execution::any_executor<SupportableProperties...> result_type;-};-+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_ANY_EXECUTOR_HPP+#define ASIO_EXECUTION_ANY_EXECUTOR_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <new>+#include <typeinfo>+#include "asio/detail/assert.hpp"+#include "asio/detail/atomic_count.hpp"+#include "asio/detail/cstddef.hpp"+#include "asio/detail/executor_function.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/non_const_lvalue.hpp"+#include "asio/detail/scoped_ptr.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/throw_exception.hpp"+#include "asio/detail/variadic_templates.hpp"+#include "asio/execution/bad_executor.hpp"+#include "asio/execution/blocking.hpp"+#include "asio/execution/execute.hpp"+#include "asio/execution/executor.hpp"+#include "asio/prefer.hpp"+#include "asio/query.hpp"+#include "asio/require.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++#if defined(GENERATING_DOCUMENTATION)++namespace execution {++/// Polymorphic executor wrapper.+template <typename... SupportableProperties>+class any_executor+{+public:+  /// Default constructor.+  any_executor() noexcept;++  /// Construct in an empty state. Equivalent effects to default constructor.+  any_executor(nullptr_t) noexcept;++  /// Copy constructor.+  any_executor(const any_executor& e) noexcept;++  /// Move constructor.+  any_executor(any_executor&& e) noexcept;++  /// Construct to point to the same target as another any_executor.+  template <class... OtherSupportableProperties>+    any_executor(any_executor<OtherSupportableProperties...> e);++  /// Construct to point to the same target as another any_executor.+  template <class... OtherSupportableProperties>+    any_executor(std::nothrow_t,+      any_executor<OtherSupportableProperties...> e) noexcept;++  /// Construct to point to the same target as another any_executor.+  any_executor(std::nothrow_t, const any_executor& e) noexcept;++  /// Construct to point to the same target as another any_executor.+  any_executor(std::nothrow_t, any_executor&& e) noexcept;++  /// Construct a polymorphic wrapper for the specified executor.+  template <typename Executor>+  any_executor(Executor e);++  /// Construct a polymorphic wrapper for the specified executor.+  template <typename Executor>+  any_executor(std::nothrow_t, Executor e) noexcept;++  /// Assignment operator.+  any_executor& operator=(const any_executor& e) noexcept;++  /// Move assignment operator.+  any_executor& operator=(any_executor&& e) noexcept;++  /// Assignment operator that sets the polymorphic wrapper to the empty state.+  any_executor& operator=(nullptr_t);++  /// Assignment operator to create a polymorphic wrapper for the specified+  /// executor.+  template <typename Executor>+  any_executor& operator=(Executor e);++  /// Destructor.+  ~any_executor();++  /// Swap targets with another polymorphic wrapper.+  void swap(any_executor& other) noexcept;++  /// Obtain a polymorphic wrapper with the specified property.+  /**+   * Do not call this function directly. It is intended for use with the+   * asio::require and asio::prefer customisation points.+   *+   * For example:+   * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;+   * auto ex2 = asio::requre(ex, execution::blocking.possibly); @endcode+   */+  template <typename Property>+  any_executor require(Property) const;++  /// Obtain a polymorphic wrapper with the specified property.+  /**+   * Do not call this function directly. It is intended for use with the+   * asio::prefer customisation point.+   *+   * For example:+   * @code execution::any_executor<execution::blocking_t::possibly_t> ex = ...;+   * auto ex2 = asio::prefer(ex, execution::blocking.possibly); @endcode+   */+  template <typename Property>+  any_executor prefer(Property) const;++  /// Obtain the value associated with the specified property.+  /**+   * Do not call this function directly. It is intended for use with the+   * asio::query customisation point.+   *+   * For example:+   * @code execution::any_executor<execution::occupancy_t> ex = ...;+   * size_t n = asio::query(ex, execution::occupancy); @endcode+   */+  template <typename Property>+  typename Property::polymorphic_query_result_type query(Property) const;++  /// Execute the function on the target executor.+  /**+   * Throws asio::bad_executor if the polymorphic wrapper has no target.+   */+  template <typename Function>+  void execute(Function&& f) const;++  /// Obtain the underlying execution context.+  /**+   * This function is provided for backward compatibility. It is automatically+   * defined when the @c SupportableProperties... list includes a property of+   * type <tt>execution::context_as<U></tt>, for some type <tt>U</tt>.+   */+  automatically_determined context() const;++  /// Determine whether the wrapper has a target executor.+  /**+   * @returns @c true if the polymorphic wrapper has a target executor,+   * otherwise false.+   */+  explicit operator bool() const noexcept;++  /// Get the type of the target executor.+  const type_info& target_type() const noexcept;++  /// Get a pointer to the target executor.+  template <typename Executor> Executor* target() noexcept;++  /// Get a pointer to the target executor.+  template <typename Executor> const Executor* target() const noexcept;+};++/// Equality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator==(const any_executor<SupportableProperties...>& a,+    const any_executor<SupportableProperties...>& b) noexcept;++/// Equality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator==(const any_executor<SupportableProperties...>& a,+    nullptr_t) noexcept;++/// Equality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator==(nullptr_t,+    const any_executor<SupportableProperties...>& b) noexcept;++/// Inequality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator!=(const any_executor<SupportableProperties...>& a,+    const any_executor<SupportableProperties...>& b) noexcept;++/// Inequality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator!=(const any_executor<SupportableProperties...>& a,+    nullptr_t) noexcept;++/// Inequality operator.+/**+ * @relates any_executor+ */+template <typename... SupportableProperties>+bool operator!=(nullptr_t,+    const any_executor<SupportableProperties...>& b) noexcept;++} // namespace execution++#else // defined(GENERATING_DOCUMENTATION)++namespace execution {++#if !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)+#define ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... SupportableProperties>+class any_executor;++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void>+class any_executor;++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)++template <typename U>+struct context_as_t;++namespace detail {++// Traits used to detect whether a property is requirable or preferable, taking+// into account that T::is_requirable or T::is_preferable may not not be well+// formed.++template <typename T, typename = void>+struct is_requirable : false_type {};++template <typename T>+struct is_requirable<T, typename enable_if<T::is_requirable>::type> :+  true_type {};++template <typename T, typename = void>+struct is_preferable : false_type {};++template <typename T>+struct is_preferable<T, typename enable_if<T::is_preferable>::type> :+  true_type {};++// Trait used to detect context_as property, for backward compatibility.++template <typename T>+struct is_context_as : false_type {};++template <typename U>+struct is_context_as<context_as_t<U> > : true_type {};++// Helper template to:+// - Check if a target can supply the supportable properties.+// - Find the first convertible-from-T property in the list.++template <std::size_t I, typename Props>+struct supportable_properties;++template <std::size_t I, typename Prop>+struct supportable_properties<I, void(Prop)>+{+  template <typename T>+  struct is_valid_target : integral_constant<bool,+      (+        is_requirable<Prop>::value+          ? can_require<T, Prop>::value+          : true+      )+      &&+      (+        is_preferable<Prop>::value+          ? can_prefer<T, Prop>::value+          : true+      )+      &&+      (+        !is_requirable<Prop>::value && !is_preferable<Prop>::value+          ? can_query<T, Prop>::value+          : true+      )+    >+  {+  };++  struct found+  {+    ASIO_STATIC_CONSTEXPR(bool, value = true);+    typedef Prop type;+    typedef typename Prop::polymorphic_query_result_type query_result_type;+    ASIO_STATIC_CONSTEXPR(std::size_t, index = I);+  };++  struct not_found+  {+    ASIO_STATIC_CONSTEXPR(bool, value = false);+  };++  template <typename T>+  struct find_convertible_property :+      conditional<+        is_same<T, Prop>::value || is_convertible<T, Prop>::value,+        found,+        not_found+      >::type {};++  template <typename T>+  struct find_convertible_requirable_property :+      conditional<+        is_requirable<Prop>::value+          && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),+        found,+        not_found+      >::type {};++  template <typename T>+  struct find_convertible_preferable_property :+      conditional<+        is_preferable<Prop>::value+          && (is_same<T, Prop>::value || is_convertible<T, Prop>::value),+        found,+        not_found+      >::type {};++  struct find_context_as_property :+      conditional<+        is_context_as<Prop>::value,+        found,+        not_found+      >::type {};+};++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <std::size_t I, typename Head, typename... Tail>+struct supportable_properties<I, void(Head, Tail...)>+{+  template <typename T>+  struct is_valid_target : integral_constant<bool,+      (+        supportable_properties<I,+          void(Head)>::template is_valid_target<T>::value+        &&+        supportable_properties<I + 1,+          void(Tail...)>::template is_valid_target<T>::value+      )+    >+  {+  };++  template <typename T>+  struct find_convertible_property :+      conditional<+        is_convertible<T, Head>::value,+        typename supportable_properties<I, void(Head)>::found,+        typename supportable_properties<I + 1,+            void(Tail...)>::template find_convertible_property<T>+      >::type {};++  template <typename T>+  struct find_convertible_requirable_property :+      conditional<+        is_requirable<Head>::value+          && is_convertible<T, Head>::value,+        typename supportable_properties<I, void(Head)>::found,+        typename supportable_properties<I + 1,+            void(Tail...)>::template find_convertible_requirable_property<T>+      >::type {};++  template <typename T>+  struct find_convertible_preferable_property :+      conditional<+        is_preferable<Head>::value+          && is_convertible<T, Head>::value,+        typename supportable_properties<I, void(Head)>::found,+        typename supportable_properties<I + 1,+            void(Tail...)>::template find_convertible_preferable_property<T>+      >::type {};++  struct find_context_as_property :+      conditional<+        is_context_as<Head>::value,+        typename supportable_properties<I, void(Head)>::found,+        typename supportable_properties<I + 1,+            void(Tail...)>::find_context_as_property+      >::type {};+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF(n) \+  template <std::size_t I, \+    typename Head, ASIO_VARIADIC_TPARAMS(n)> \+  struct supportable_properties<I, \+      void(Head, ASIO_VARIADIC_TARGS(n))> \+  { \+    template <typename T> \+    struct is_valid_target : integral_constant<bool, \+        ( \+          supportable_properties<I, \+            void(Head)>::template is_valid_target<T>::value \+          && \+          supportable_properties<I + 1, \+              void(ASIO_VARIADIC_TARGS(n))>::template \+                is_valid_target<T>::value \+        ) \+      > \+    { \+    }; \+  \+    template <typename T> \+    struct find_convertible_property : \+        conditional< \+          is_convertible<T, Head>::value, \+          typename supportable_properties<I, void(Head)>::found, \+          typename supportable_properties<I + 1, \+              void(ASIO_VARIADIC_TARGS(n))>::template \+                find_convertible_property<T> \+        >::type {}; \+  \+    template <typename T> \+    struct find_convertible_requirable_property : \+        conditional< \+          is_requirable<Head>::value \+            && is_convertible<T, Head>::value, \+          typename supportable_properties<I, void(Head)>::found, \+          typename supportable_properties<I + 1, \+              void(ASIO_VARIADIC_TARGS(n))>::template \+                find_convertible_requirable_property<T> \+        >::type {}; \+  \+    template <typename T> \+    struct find_convertible_preferable_property : \+        conditional< \+          is_preferable<Head>::value \+            && is_convertible<T, Head>::value, \+          typename supportable_properties<I, void(Head)>::found, \+          typename supportable_properties<I + 1, \+              void(ASIO_VARIADIC_TARGS(n))>::template \+                find_convertible_preferable_property<T> \+        >::type {}; \+  \+    struct find_context_as_property : \+        conditional< \+          is_context_as<Head>::value, \+          typename supportable_properties<I, void(Head)>::found, \+          typename supportable_properties<I + 1, void( \+            ASIO_VARIADIC_TARGS(n))>::find_context_as_property \+        >::type {}; \+  }; \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROPS_BASE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename Props>+struct is_valid_target_executor :+  conditional<+    is_executor<T>::value,+    typename supportable_properties<0, Props>::template is_valid_target<T>,+    false_type+  >::type+{+};++template <typename Props>+struct is_valid_target_executor<int, Props> : false_type+{+};++class shared_target_executor+{+public:+  template <typename E>+  shared_target_executor(ASIO_MOVE_ARG(E) e,+      typename decay<E>::type*& target)+  {+    impl<typename decay<E>::type>* i =+      new impl<typename decay<E>::type>(ASIO_MOVE_CAST(E)(e));+    target = &i->ex_;+    impl_ = i;+  }++  template <typename E>+  shared_target_executor(std::nothrow_t, ASIO_MOVE_ARG(E) e,+      typename decay<E>::type*& target) ASIO_NOEXCEPT+  {+    impl<typename decay<E>::type>* i =+      new (std::nothrow) impl<typename decay<E>::type>(+        ASIO_MOVE_CAST(E)(e));+    target = i ? &i->ex_ : 0;+    impl_ = i;+  }++  shared_target_executor(+      const shared_target_executor& other) ASIO_NOEXCEPT+    : impl_(other.impl_)+  {+    if (impl_)+      asio::detail::ref_count_up(impl_->ref_count_);+  }++  shared_target_executor& operator=(+      const shared_target_executor& other) ASIO_NOEXCEPT+  {+    impl_ = other.impl_;+    if (impl_)+      asio::detail::ref_count_up(impl_->ref_count_);+    return *this;+  }++#if defined(ASIO_HAS_MOVE)+  shared_target_executor(+      shared_target_executor&& other) ASIO_NOEXCEPT+    : impl_(other.impl_)+  {+    other.impl_ = 0;+  }++  shared_target_executor& operator=(+      shared_target_executor&& other) ASIO_NOEXCEPT+  {+    impl_ = other.impl_;+    other.impl_ = 0;+    return *this;+  }+#endif // defined(ASIO_HAS_MOVE)++  ~shared_target_executor()+  {+    if (impl_)+      if (asio::detail::ref_count_down(impl_->ref_count_))+        delete impl_;+  }++  void* get() const ASIO_NOEXCEPT+  {+    return impl_ ? impl_->get() : 0;+  }++private:+  struct impl_base+  {+    impl_base() : ref_count_(1) {}+    virtual ~impl_base() {}+    virtual void* get() = 0;+    asio::detail::atomic_count ref_count_;+  };++  template <typename Executor>+  struct impl : impl_base+  {+    impl(Executor ex) : ex_(ASIO_MOVE_CAST(Executor)(ex)) {}+    virtual void* get() { return &ex_; }+    Executor ex_;+  };++  impl_base* impl_;+};++class any_executor_base+{+public:+  any_executor_base() ASIO_NOEXCEPT+    : object_fns_(0),+      target_(0),+      target_fns_(0)+  {+  }++  template <ASIO_EXECUTION_EXECUTOR Executor>+  any_executor_base(Executor ex, false_type)+    : target_fns_(target_fns_table<Executor>(+          any_executor_base::query_blocking(ex,+            can_query<const Executor&, const execution::blocking_t&>())+          == execution::blocking.always))+  {+    any_executor_base::construct_object(ex,+        integral_constant<bool,+          sizeof(Executor) <= sizeof(object_type)+            && alignment_of<Executor>::value <= alignment_of<object_type>::value+        >());+  }++  template <ASIO_EXECUTION_EXECUTOR Executor>+  any_executor_base(std::nothrow_t, Executor ex, false_type) ASIO_NOEXCEPT+    : target_fns_(target_fns_table<Executor>(+          any_executor_base::query_blocking(ex,+            can_query<const Executor&, const execution::blocking_t&>())+          == execution::blocking.always))+  {+    any_executor_base::construct_object(std::nothrow, ex,+        integral_constant<bool,+          sizeof(Executor) <= sizeof(object_type)+            && alignment_of<Executor>::value <= alignment_of<object_type>::value+        >());+    if (target_ == 0)+    {+      object_fns_ = 0;+      target_fns_ = 0;+    }+  }++  template <ASIO_EXECUTION_EXECUTOR Executor>+  any_executor_base(Executor other, true_type)+    : object_fns_(object_fns_table<shared_target_executor>()),+      target_fns_(other.target_fns_)+  {+    Executor* p = 0;+    new (&object_) shared_target_executor(+        ASIO_MOVE_CAST(Executor)(other), p);+    target_ = p->template target<void>();+  }++  template <ASIO_EXECUTION_EXECUTOR Executor>+  any_executor_base(std::nothrow_t,+      Executor other, true_type) ASIO_NOEXCEPT+    : object_fns_(object_fns_table<shared_target_executor>()),+      target_fns_(other.target_fns_)+  {+    Executor* p = 0;+    new (&object_) shared_target_executor(+        std::nothrow, ASIO_MOVE_CAST(Executor)(other), p);+    if (p)+      target_ = p->template target<void>();+    else+    {+      target_ = 0;+      object_fns_ = 0;+      target_fns_ = 0;+    }+  }++  any_executor_base(const any_executor_base& other) ASIO_NOEXCEPT+  {+    if (!!other)+    {+      object_fns_ = other.object_fns_;+      target_fns_ = other.target_fns_;+      object_fns_->copy(*this, other);+    }+    else+    {+      object_fns_ = 0;+      target_ = 0;+      target_fns_ = 0;+    }+  }++  ~any_executor_base() ASIO_NOEXCEPT+  {+    if (!!*this)+      object_fns_->destroy(*this);+  }++  any_executor_base& operator=(+      const any_executor_base& other) ASIO_NOEXCEPT+  {+    if (this != &other)+    {+      if (!!*this)+        object_fns_->destroy(*this);+      if (!!other)+      {+        object_fns_ = other.object_fns_;+        target_fns_ = other.target_fns_;+        object_fns_->copy(*this, other);+      }+      else+      {+        object_fns_ = 0;+        target_ = 0;+        target_fns_ = 0;+      }+    }+    return *this;+  }++  any_executor_base& operator=(nullptr_t) ASIO_NOEXCEPT+  {+    if (target_)+      object_fns_->destroy(*this);+    target_ = 0;+    object_fns_ = 0;+    target_fns_ = 0;+    return *this;+  }++#if defined(ASIO_HAS_MOVE)++  any_executor_base(any_executor_base&& other) ASIO_NOEXCEPT+  {+    if (other.target_)+    {+      object_fns_ = other.object_fns_;+      target_fns_ = other.target_fns_;+      other.object_fns_ = 0;+      other.target_fns_ = 0;+      object_fns_->move(*this, other);+      other.target_ = 0;+    }+    else+    {+      object_fns_ = 0;+      target_ = 0;+      target_fns_ = 0;+    }+  }++  any_executor_base& operator=(+      any_executor_base&& other) ASIO_NOEXCEPT+  {+    if (this != &other)+    {+      if (!!*this)+        object_fns_->destroy(*this);+      if (!!other)+      {+        object_fns_ = other.object_fns_;+        target_fns_ = other.target_fns_;+        other.object_fns_ = 0;+        other.target_fns_ = 0;+        object_fns_->move(*this, other);+        other.target_ = 0;+      }+      else+      {+        object_fns_ = 0;+        target_ = 0;+        target_fns_ = 0;+      }+    }+    return *this;+  }++#endif // defined(ASIO_HAS_MOVE)++  void swap(any_executor_base& other) ASIO_NOEXCEPT+  {+    if (this != &other)+    {+      any_executor_base tmp(ASIO_MOVE_CAST(any_executor_base)(other));+      other = ASIO_MOVE_CAST(any_executor_base)(*this);+      *this = ASIO_MOVE_CAST(any_executor_base)(tmp);+    }+  }++  template <typename F>+  void execute(ASIO_MOVE_ARG(F) f) const+  {+    if (target_)+    {+      if (target_fns_->blocking_execute != 0)+      {+        asio::detail::non_const_lvalue<F> f2(f);+        target_fns_->blocking_execute(*this, function_view(f2.value));+      }+      else+      {+        target_fns_->execute(*this,+            function(ASIO_MOVE_CAST(F)(f), std::allocator<void>()));+      }+    }+    else+    {+      bad_executor ex;+      asio::detail::throw_exception(ex);+    }+  }++  template <typename Executor>+  Executor* target()+  {+    return target_ && (is_same<Executor, void>::value+        || target_fns_->target_type() == target_type_ex<Executor>())+      ? static_cast<Executor*>(target_) : 0;+  }++  template <typename Executor>+  const Executor* target() const+  {+    return target_ && (is_same<Executor, void>::value+        || target_fns_->target_type() == target_type_ex<Executor>())+      ? static_cast<const Executor*>(target_) : 0;+  }++#if !defined(ASIO_NO_TYPEID)+  const std::type_info& target_type() const+  {+    return target_ ? target_fns_->target_type() : typeid(void);+  }+#else // !defined(ASIO_NO_TYPEID)+  const void* target_type() const+  {+    return target_ ? target_fns_->target_type() : 0;+  }+#endif // !defined(ASIO_NO_TYPEID)++  struct unspecified_bool_type_t {};+  typedef void (*unspecified_bool_type)(unspecified_bool_type_t);+  static void unspecified_bool_true(unspecified_bool_type_t) {}++  operator unspecified_bool_type() const ASIO_NOEXCEPT+  {+    return target_ ? &any_executor_base::unspecified_bool_true : 0;+  }++  bool operator!() const ASIO_NOEXCEPT+  {+    return target_ == 0;+  }++protected:+  bool equality_helper(const any_executor_base& other) const ASIO_NOEXCEPT+  {+    if (target_ == other.target_)+      return true;+    if (target_ && !other.target_)+      return false;+    if (!target_ && other.target_)+      return false;+    if (target_fns_ != other.target_fns_)+      return false;+    return target_fns_->equal(*this, other);+  }++  template <typename Ex>+  Ex& object()+  {+    return *static_cast<Ex*>(static_cast<void*>(&object_));+  }++  template <typename Ex>+  const Ex& object() const+  {+    return *static_cast<const Ex*>(static_cast<const void*>(&object_));+  }++  struct object_fns+  {+    void (*destroy)(any_executor_base&);+    void (*copy)(any_executor_base&, const any_executor_base&);+    void (*move)(any_executor_base&, any_executor_base&);+    const void* (*target)(const any_executor_base&);+  };++  static void destroy_shared(any_executor_base& ex)+  {+    typedef shared_target_executor type;+    ex.object<type>().~type();+  }++  static void copy_shared(any_executor_base& ex1, const any_executor_base& ex2)+  {+    typedef shared_target_executor type;+    new (&ex1.object_) type(ex2.object<type>());+    ex1.target_ = ex2.target_;+  }++  static void move_shared(any_executor_base& ex1, any_executor_base& ex2)+  {+    typedef shared_target_executor type;+    new (&ex1.object_) type(ASIO_MOVE_CAST(type)(ex2.object<type>()));+    ex1.target_ = ex2.target_;+    ex2.object<type>().~type();+  }++  static const void* target_shared(const any_executor_base& ex)+  {+    typedef shared_target_executor type;+    return ex.object<type>().get();+  }++  template <typename Obj>+  static const object_fns* object_fns_table(+      typename enable_if<+        is_same<Obj, shared_target_executor>::value+      >::type* = 0)+  {+    static const object_fns fns =+    {+      &any_executor_base::destroy_shared,+      &any_executor_base::copy_shared,+      &any_executor_base::move_shared,+      &any_executor_base::target_shared+    };+    return &fns;+  }++  template <typename Obj>+  static void destroy_object(any_executor_base& ex)+  {+    ex.object<Obj>().~Obj();+  }++  template <typename Obj>+  static void copy_object(any_executor_base& ex1, const any_executor_base& ex2)+  {+    new (&ex1.object_) Obj(ex2.object<Obj>());+    ex1.target_ = &ex1.object<Obj>();+  }++  template <typename Obj>+  static void move_object(any_executor_base& ex1, any_executor_base& ex2)+  {+    new (&ex1.object_) Obj(ASIO_MOVE_CAST(Obj)(ex2.object<Obj>()));+    ex1.target_ = &ex1.object<Obj>();+    ex2.object<Obj>().~Obj();+  }++  template <typename Obj>+  static const void* target_object(const any_executor_base& ex)+  {+    return &ex.object<Obj>();+  }++  template <typename Obj>+  static const object_fns* object_fns_table(+      typename enable_if<+        !is_same<Obj, void>::value+          && !is_same<Obj, shared_target_executor>::value+      >::type* = 0)+  {+    static const object_fns fns =+    {+      &any_executor_base::destroy_object<Obj>,+      &any_executor_base::copy_object<Obj>,+      &any_executor_base::move_object<Obj>,+      &any_executor_base::target_object<Obj>+    };+    return &fns;+  }++  typedef asio::detail::executor_function function;+  typedef asio::detail::executor_function_view function_view;++  struct target_fns+  {+#if !defined(ASIO_NO_TYPEID)+    const std::type_info& (*target_type)();+#else // !defined(ASIO_NO_TYPEID)+    const void* (*target_type)();+#endif // !defined(ASIO_NO_TYPEID)+    bool (*equal)(const any_executor_base&, const any_executor_base&);+    void (*execute)(const any_executor_base&, ASIO_MOVE_ARG(function));+    void (*blocking_execute)(const any_executor_base&, function_view);+  };++#if !defined(ASIO_NO_TYPEID)+  template <typename Ex>+  static const std::type_info& target_type_ex()+  {+    return typeid(Ex);+  }+#else // !defined(ASIO_NO_TYPEID)+  template <typename Ex>+  static const void* target_type_ex()+  {+    static int unique_id;+    return &unique_id;+  }+#endif // !defined(ASIO_NO_TYPEID)++  template <typename Ex>+  static bool equal_ex(const any_executor_base& ex1,+      const any_executor_base& ex2)+  {+    const Ex* p1 = ex1.target<Ex>();+    const Ex* p2 = ex2.target<Ex>();+    ASIO_ASSUME(p1 != 0 && p2 != 0);+    return *p1 == *p2;+  }++  template <typename Ex>+  static void execute_ex(const any_executor_base& ex,+      ASIO_MOVE_ARG(function) f)+  {+    const Ex* p = ex.target<Ex>();+    ASIO_ASSUME(p != 0);+#if defined(ASIO_NO_DEPRECATED)+    p->execute(ASIO_MOVE_CAST(function)(f));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(*p, ASIO_MOVE_CAST(function)(f));+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Ex>+  static void blocking_execute_ex(const any_executor_base& ex, function_view f)+  {+    const Ex* p = ex.target<Ex>();+    ASIO_ASSUME(p != 0);+#if defined(ASIO_NO_DEPRECATED)+    p->execute(f);+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(*p, f);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Ex>+  static const target_fns* target_fns_table(bool is_always_blocking,+      typename enable_if<+        !is_same<Ex, void>::value+      >::type* = 0)+  {+    static const target_fns fns_with_execute =+    {+      &any_executor_base::target_type_ex<Ex>,+      &any_executor_base::equal_ex<Ex>,+      &any_executor_base::execute_ex<Ex>,+      0+    };++    static const target_fns fns_with_blocking_execute =+    {+      &any_executor_base::target_type_ex<Ex>,+      &any_executor_base::equal_ex<Ex>,+      0,+      &any_executor_base::blocking_execute_ex<Ex>+    };++    return is_always_blocking ? &fns_with_blocking_execute : &fns_with_execute;+  }++#if defined(ASIO_MSVC)+# pragma warning (push)+# pragma warning (disable:4702)+#endif // defined(ASIO_MSVC)++  static void query_fn_void(void*, const void*, const void*)+  {+    bad_executor ex;+    asio::detail::throw_exception(ex);+  }++  template <typename Ex, class Prop>+  static void query_fn_non_void(void*, const void* ex, const void* prop,+      typename enable_if<+        asio::can_query<const Ex&, const Prop&>::value+          && is_same<typename Prop::polymorphic_query_result_type, void>::value+      >::type*)+  {+    asio::query(*static_cast<const Ex*>(ex),+        *static_cast<const Prop*>(prop));+  }++  template <typename Ex, class Prop>+  static void query_fn_non_void(void*, const void*, const void*,+      typename enable_if<+        !asio::can_query<const Ex&, const Prop&>::value+          && is_same<typename Prop::polymorphic_query_result_type, void>::value+      >::type*)+  {+  }++  template <typename Ex, class Prop>+  static void query_fn_non_void(void* result, const void* ex, const void* prop,+      typename enable_if<+        asio::can_query<const Ex&, const Prop&>::value+          && !is_same<typename Prop::polymorphic_query_result_type, void>::value+          && is_reference<typename Prop::polymorphic_query_result_type>::value+      >::type*)+  {+    *static_cast<typename remove_reference<+      typename Prop::polymorphic_query_result_type>::type**>(result)+        = &static_cast<typename Prop::polymorphic_query_result_type>(+            asio::query(*static_cast<const Ex*>(ex),+              *static_cast<const Prop*>(prop)));+  }++  template <typename Ex, class Prop>+  static void query_fn_non_void(void*, const void*, const void*,+      typename enable_if<+        !asio::can_query<const Ex&, const Prop&>::value+          && !is_same<typename Prop::polymorphic_query_result_type, void>::value+          && is_reference<typename Prop::polymorphic_query_result_type>::value+      >::type*)+  {+    std::terminate(); // Combination should not be possible.+  }++  template <typename Ex, class Prop>+  static void query_fn_non_void(void* result, const void* ex, const void* prop,+      typename enable_if<+        asio::can_query<const Ex&, const Prop&>::value+          && !is_same<typename Prop::polymorphic_query_result_type, void>::value+          && is_scalar<typename Prop::polymorphic_query_result_type>::value+      >::type*)+  {+    *static_cast<typename Prop::polymorphic_query_result_type*>(result)+      = static_cast<typename Prop::polymorphic_query_result_type>(+          asio::query(*static_cast<const Ex*>(ex),+            *static_cast<const Prop*>(prop)));+  }++  template <typename Ex, class Prop>+  static void query_fn_non_void(void* result, const void*, const void*,+      typename enable_if<+        !asio::can_query<const Ex&, const Prop&>::value+          && !is_same<typename Prop::polymorphic_query_result_type, void>::value+          && is_scalar<typename Prop::polymorphic_query_result_type>::value+      >::type*)+  {+    *static_cast<typename Prop::polymorphic_query_result_type*>(result)+      = typename Prop::polymorphic_query_result_type();+  }++  template <typename Ex, class Prop>+  static void query_fn_non_void(void* result, const void* ex, const void* prop,+      typename enable_if<+        asio::can_query<const Ex&, const Prop&>::value+          && !is_same<typename Prop::polymorphic_query_result_type, void>::value+          && !is_reference<typename Prop::polymorphic_query_result_type>::value+          && !is_scalar<typename Prop::polymorphic_query_result_type>::value+      >::type*)+  {+    *static_cast<typename Prop::polymorphic_query_result_type**>(result)+      = new typename Prop::polymorphic_query_result_type(+          asio::query(*static_cast<const Ex*>(ex),+            *static_cast<const Prop*>(prop)));+  }++  template <typename Ex, class Prop>+  static void query_fn_non_void(void* result, const void*, const void*, ...)+  {+    *static_cast<typename Prop::polymorphic_query_result_type**>(result)+      = new typename Prop::polymorphic_query_result_type();+  }++  template <typename Ex, class Prop>+  static void query_fn_impl(void* result, const void* ex, const void* prop,+      typename enable_if<+        is_same<Ex, void>::value+      >::type*)+  {+    query_fn_void(result, ex, prop);+  }++  template <typename Ex, class Prop>+  static void query_fn_impl(void* result, const void* ex, const void* prop,+      typename enable_if<+        !is_same<Ex, void>::value+      >::type*)+  {+    query_fn_non_void<Ex, Prop>(result, ex, prop, 0);+  }++  template <typename Ex, class Prop>+  static void query_fn(void* result, const void* ex, const void* prop)+  {+    query_fn_impl<Ex, Prop>(result, ex, prop, 0);+  }++  template <typename Poly, typename Ex, class Prop>+  static Poly require_fn_impl(const void*, const void*,+      typename enable_if<+        is_same<Ex, void>::value+      >::type*)+  {+    bad_executor ex;+    asio::detail::throw_exception(ex);+    return Poly();+  }++  template <typename Poly, typename Ex, class Prop>+  static Poly require_fn_impl(const void* ex, const void* prop,+      typename enable_if<+        !is_same<Ex, void>::value && Prop::is_requirable+      >::type*)+  {+    return asio::require(*static_cast<const Ex*>(ex),+        *static_cast<const Prop*>(prop));+  }++  template <typename Poly, typename Ex, class Prop>+  static Poly require_fn_impl(const void*, const void*, ...)+  {+    return Poly();+  }++  template <typename Poly, typename Ex, class Prop>+  static Poly require_fn(const void* ex, const void* prop)+  {+    return require_fn_impl<Poly, Ex, Prop>(ex, prop, 0);+  }++  template <typename Poly, typename Ex, class Prop>+  static Poly prefer_fn_impl(const void*, const void*,+      typename enable_if<+        is_same<Ex, void>::value+      >::type*)+  {+    bad_executor ex;+    asio::detail::throw_exception(ex);+    return Poly();+  }++  template <typename Poly, typename Ex, class Prop>+  static Poly prefer_fn_impl(const void* ex, const void* prop,+      typename enable_if<+        !is_same<Ex, void>::value && Prop::is_preferable+      >::type*)+  {+    return asio::prefer(*static_cast<const Ex*>(ex),+        *static_cast<const Prop*>(prop));+  }++  template <typename Poly, typename Ex, class Prop>+  static Poly prefer_fn_impl(const void*, const void*, ...)+  {+    return Poly();+  }++  template <typename Poly, typename Ex, class Prop>+  static Poly prefer_fn(const void* ex, const void* prop)+  {+    return prefer_fn_impl<Poly, Ex, Prop>(ex, prop, 0);+  }++  template <typename Poly>+  struct prop_fns+  {+    void (*query)(void*, const void*, const void*);+    Poly (*require)(const void*, const void*);+    Poly (*prefer)(const void*, const void*);+  };++#if defined(ASIO_MSVC)+# pragma warning (pop)+#endif // defined(ASIO_MSVC)++private:+  template <typename Executor>+  static execution::blocking_t query_blocking(const Executor& ex, true_type)+  {+    return asio::query(ex, execution::blocking);+  }++  template <typename Executor>+  static execution::blocking_t query_blocking(const Executor&, false_type)+  {+    return execution::blocking_t();+  }++  template <typename Executor>+  void construct_object(Executor& ex, true_type)+  {+    object_fns_ = object_fns_table<Executor>();+    target_ = new (&object_) Executor(ASIO_MOVE_CAST(Executor)(ex));+  }++  template <typename Executor>+  void construct_object(Executor& ex, false_type)+  {+    object_fns_ = object_fns_table<shared_target_executor>();+    Executor* p = 0;+    new (&object_) shared_target_executor(+        ASIO_MOVE_CAST(Executor)(ex), p);+    target_ = p;+  }++  template <typename Executor>+  void construct_object(std::nothrow_t,+      Executor& ex, true_type) ASIO_NOEXCEPT+  {+    object_fns_ = object_fns_table<Executor>();+    target_ = new (&object_) Executor(ASIO_MOVE_CAST(Executor)(ex));+  }++  template <typename Executor>+  void construct_object(std::nothrow_t,+      Executor& ex, false_type) ASIO_NOEXCEPT+  {+    object_fns_ = object_fns_table<shared_target_executor>();+    Executor* p = 0;+    new (&object_) shared_target_executor(+        std::nothrow, ASIO_MOVE_CAST(Executor)(ex), p);+    target_ = p;+  }++/*private:*/public:+//  template <typename...> friend class any_executor;++  typedef aligned_storage<+      sizeof(asio::detail::shared_ptr<void>) + sizeof(void*),+      alignment_of<asio::detail::shared_ptr<void> >::value+    >::type object_type;++  object_type object_;+  const object_fns* object_fns_;+  void* target_;+  const target_fns* target_fns_;+};++template <typename Derived, typename Property, typename = void>+struct any_executor_context+{+};++#if !defined(ASIO_NO_TS_EXECUTORS)++template <typename Derived, typename Property>+struct any_executor_context<Derived, Property,+    typename enable_if<Property::value>::type>+{+  typename Property::query_result_type context() const+  {+    return static_cast<const Derived*>(this)->query(typename Property::type());+  }+};++#endif // !defined(ASIO_NO_TS_EXECUTORS)++} // namespace detail++template <>+class any_executor<> : public detail::any_executor_base+{+public:+  any_executor() ASIO_NOEXCEPT+    : detail::any_executor_base()+  {+  }++  any_executor(nullptr_t) ASIO_NOEXCEPT+    : detail::any_executor_base()+  {+  }++  template <typename Executor>+  any_executor(Executor ex,+      typename enable_if<+        conditional<+          !is_same<Executor, any_executor>::value+            && !is_base_of<detail::any_executor_base, Executor>::value,+          is_executor<Executor>,+          false_type+        >::type::value+      >::type* = 0)+    : detail::any_executor_base(+        ASIO_MOVE_CAST(Executor)(ex), false_type())+  {+  }++  template <typename Executor>+  any_executor(std::nothrow_t, Executor ex,+      typename enable_if<+        conditional<+          !is_same<Executor, any_executor>::value+            && !is_base_of<detail::any_executor_base, Executor>::value,+          is_executor<Executor>,+          false_type+        >::type::value+      >::type* = 0) ASIO_NOEXCEPT+    : detail::any_executor_base(std::nothrow,+        ASIO_MOVE_CAST(Executor)(ex), false_type())+  {+  }++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename... OtherSupportableProperties>+  any_executor(any_executor<OtherSupportableProperties...> other)+    : detail::any_executor_base(+        static_cast<const detail::any_executor_base&>(other))+  {+  }++  template <typename... OtherSupportableProperties>+  any_executor(std::nothrow_t,+      any_executor<OtherSupportableProperties...> other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<const detail::any_executor_base&>(other))+  {+  }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename U0, typename U1, typename U2, typename U3,+      typename U4, typename U5, typename U6, typename U7>+  any_executor(any_executor<U0, U1, U2, U3, U4, U5, U6, U7> other)+    : detail::any_executor_base(+        static_cast<const detail::any_executor_base&>(other))+  {+  }++  template <typename U0, typename U1, typename U2, typename U3,+      typename U4, typename U5, typename U6, typename U7>+  any_executor(std::nothrow_t,+      any_executor<U0, U1, U2, U3, U4, U5, U6, U7> other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<const detail::any_executor_base&>(other))+  {+  }++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  any_executor(const any_executor& other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<const detail::any_executor_base&>(other))+  {+  }++  any_executor(std::nothrow_t, const any_executor& other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<const detail::any_executor_base&>(other))+  {+  }++  any_executor& operator=(const any_executor& other) ASIO_NOEXCEPT+  {+    if (this != &other)+    {+      detail::any_executor_base::operator=(+          static_cast<const detail::any_executor_base&>(other));+    }+    return *this;+  }++  any_executor& operator=(nullptr_t p) ASIO_NOEXCEPT+  {+    detail::any_executor_base::operator=(p);+    return *this;+  }++#if defined(ASIO_HAS_MOVE)++  any_executor(any_executor&& other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<any_executor_base&&>(+          static_cast<any_executor_base&>(other)))+  {+  }++  any_executor(std::nothrow_t, any_executor&& other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<any_executor_base&&>(+          static_cast<any_executor_base&>(other)))+  {+  }++  any_executor& operator=(any_executor&& other) ASIO_NOEXCEPT+  {+    if (this != &other)+    {+      detail::any_executor_base::operator=(+          static_cast<detail::any_executor_base&&>(+            static_cast<detail::any_executor_base&>(other)));+    }+    return *this;+  }++#endif // defined(ASIO_HAS_MOVE)++  void swap(any_executor& other) ASIO_NOEXCEPT+  {+    detail::any_executor_base::swap(+        static_cast<detail::any_executor_base&>(other));+  }++  using detail::any_executor_base::execute;+  using detail::any_executor_base::target;+  using detail::any_executor_base::target_type;+  using detail::any_executor_base::operator unspecified_bool_type;+  using detail::any_executor_base::operator!;++  bool equality_helper(const any_executor& other) const ASIO_NOEXCEPT+  {+    return any_executor_base::equality_helper(other);+  }++  template <typename AnyExecutor1, typename AnyExecutor2>+  friend typename enable_if<+    is_base_of<any_executor, AnyExecutor1>::value+      || is_base_of<any_executor, AnyExecutor2>::value,+    bool+  >::type operator==(const AnyExecutor1& a,+      const AnyExecutor2& b) ASIO_NOEXCEPT+  {+    return static_cast<const any_executor&>(a).equality_helper(b);+  }++  template <typename AnyExecutor>+  friend typename enable_if<+    is_same<AnyExecutor, any_executor>::value,+    bool+  >::type operator==(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT+  {+    return !a;+  }++  template <typename AnyExecutor>+  friend typename enable_if<+    is_same<AnyExecutor, any_executor>::value,+    bool+  >::type operator==(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT+  {+    return !b;+  }++  template <typename AnyExecutor1, typename AnyExecutor2>+  friend typename enable_if<+    is_base_of<any_executor, AnyExecutor1>::value+      || is_base_of<any_executor, AnyExecutor2>::value,+    bool+  >::type operator!=(const AnyExecutor1& a,+      const AnyExecutor2& b) ASIO_NOEXCEPT+  {+    return !static_cast<const any_executor&>(a).equality_helper(b);+  }++  template <typename AnyExecutor>+  friend typename enable_if<+    is_same<AnyExecutor, any_executor>::value,+    bool+  >::type operator!=(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT+  {+    return !!a;+  }++  template <typename AnyExecutor>+  friend typename enable_if<+    is_same<AnyExecutor, any_executor>::value,+    bool+  >::type operator!=(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT+  {+    return !!b;+  }+};++inline void swap(any_executor<>& a, any_executor<>& b) ASIO_NOEXCEPT+{+  return a.swap(b);+}++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... SupportableProperties>+class any_executor :+  public detail::any_executor_base,+  public detail::any_executor_context<+    any_executor<SupportableProperties...>,+      typename detail::supportable_properties<+        0, void(SupportableProperties...)>::find_context_as_property>+{+public:+  any_executor() ASIO_NOEXCEPT+    : detail::any_executor_base(),+      prop_fns_(prop_fns_table<void>())+  {+  }++  any_executor(nullptr_t) ASIO_NOEXCEPT+    : detail::any_executor_base(),+      prop_fns_(prop_fns_table<void>())+  {+  }++  template <typename Executor>+  any_executor(Executor ex,+      typename enable_if<+        conditional<+          !is_same<Executor, any_executor>::value+            && !is_base_of<detail::any_executor_base, Executor>::value,+          detail::is_valid_target_executor<+            Executor, void(SupportableProperties...)>,+          false_type+        >::type::value+      >::type* = 0)+    : detail::any_executor_base(+        ASIO_MOVE_CAST(Executor)(ex), false_type()),+      prop_fns_(prop_fns_table<Executor>())+  {+  }++  template <typename Executor>+  any_executor(std::nothrow_t, Executor ex,+      typename enable_if<+        conditional<+          !is_same<Executor, any_executor>::value+            && !is_base_of<detail::any_executor_base, Executor>::value,+          detail::is_valid_target_executor<+            Executor, void(SupportableProperties...)>,+          false_type+        >::type::value+      >::type* = 0) ASIO_NOEXCEPT+    : detail::any_executor_base(std::nothrow,+        ASIO_MOVE_CAST(Executor)(ex), false_type()),+      prop_fns_(prop_fns_table<Executor>())+  {+    if (this->template target<void>() == 0)+      prop_fns_ = prop_fns_table<void>();+  }++  template <typename... OtherSupportableProperties>+  any_executor(any_executor<OtherSupportableProperties...> other,+      typename enable_if<+        conditional<+          !is_same<+            any_executor<OtherSupportableProperties...>,+            any_executor+          >::value,+          typename detail::supportable_properties<+            0, void(SupportableProperties...)>::template is_valid_target<+              any_executor<OtherSupportableProperties...> >,+          false_type+        >::type::value+      >::type* = 0)+    : detail::any_executor_base(ASIO_MOVE_CAST(+          any_executor<OtherSupportableProperties...>)(other), true_type()),+      prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...> >())+  {+  }++  template <typename... OtherSupportableProperties>+  any_executor(std::nothrow_t,+      any_executor<OtherSupportableProperties...> other,+      typename enable_if<+        conditional<+          !is_same<+            any_executor<OtherSupportableProperties...>,+            any_executor+          >::value,+          typename detail::supportable_properties<+            0, void(SupportableProperties...)>::template is_valid_target<+              any_executor<OtherSupportableProperties...> >,+          false_type+        >::type::value+      >::type* = 0) ASIO_NOEXCEPT+    : detail::any_executor_base(std::nothrow, ASIO_MOVE_CAST(+          any_executor<OtherSupportableProperties...>)(other), true_type()),+      prop_fns_(prop_fns_table<any_executor<OtherSupportableProperties...> >())+  {+    if (this->template target<void>() == 0)+      prop_fns_ = prop_fns_table<void>();+  }++  any_executor(const any_executor& other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<const detail::any_executor_base&>(other)),+      prop_fns_(other.prop_fns_)+  {+  }++  any_executor(std::nothrow_t, const any_executor& other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<const detail::any_executor_base&>(other)),+      prop_fns_(other.prop_fns_)+  {+  }++  any_executor& operator=(const any_executor& other) ASIO_NOEXCEPT+  {+    if (this != &other)+    {+      prop_fns_ = other.prop_fns_;+      detail::any_executor_base::operator=(+          static_cast<const detail::any_executor_base&>(other));+    }+    return *this;+  }++  any_executor& operator=(nullptr_t p) ASIO_NOEXCEPT+  {+    prop_fns_ = prop_fns_table<void>();+    detail::any_executor_base::operator=(p);+    return *this;+  }++#if defined(ASIO_HAS_MOVE)++  any_executor(any_executor&& other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<any_executor_base&&>(+          static_cast<any_executor_base&>(other))),+      prop_fns_(other.prop_fns_)+  {+    other.prop_fns_ = prop_fns_table<void>();+  }++  any_executor(std::nothrow_t, any_executor&& other) ASIO_NOEXCEPT+    : detail::any_executor_base(+        static_cast<any_executor_base&&>(+          static_cast<any_executor_base&>(other))),+      prop_fns_(other.prop_fns_)+  {+    other.prop_fns_ = prop_fns_table<void>();+  }++  any_executor& operator=(any_executor&& other) ASIO_NOEXCEPT+  {+    if (this != &other)+    {+      prop_fns_ = other.prop_fns_;+      detail::any_executor_base::operator=(+          static_cast<detail::any_executor_base&&>(+            static_cast<detail::any_executor_base&>(other)));+    }+    return *this;+  }++#endif // defined(ASIO_HAS_MOVE)++  void swap(any_executor& other) ASIO_NOEXCEPT+  {+    if (this != &other)+    {+      detail::any_executor_base::swap(+          static_cast<detail::any_executor_base&>(other));+      const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_;+      other.prop_fns_ = prop_fns_;+      prop_fns_ = tmp_prop_fns;+    }+  }++  using detail::any_executor_base::execute;+  using detail::any_executor_base::target;+  using detail::any_executor_base::target_type;+  using detail::any_executor_base::operator unspecified_bool_type;+  using detail::any_executor_base::operator!;++  bool equality_helper(const any_executor& other) const ASIO_NOEXCEPT+  {+    return any_executor_base::equality_helper(other);+  }++  template <typename AnyExecutor1, typename AnyExecutor2>+  friend typename enable_if<+    is_base_of<any_executor, AnyExecutor1>::value+      || is_base_of<any_executor, AnyExecutor2>::value,+    bool+  >::type operator==(const AnyExecutor1& a,+      const AnyExecutor2& b) ASIO_NOEXCEPT+  {+    return static_cast<const any_executor&>(a).equality_helper(b);+  }++  template <typename AnyExecutor>+  friend typename enable_if<+    is_same<AnyExecutor, any_executor>::value,+    bool+  >::type operator==(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT+  {+    return !a;+  }++  template <typename AnyExecutor>+  friend typename enable_if<+    is_same<AnyExecutor, any_executor>::value,+    bool+  >::type operator==(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT+  {+    return !b;+  }++  template <typename AnyExecutor1, typename AnyExecutor2>+  friend typename enable_if<+    is_base_of<any_executor, AnyExecutor1>::value+      || is_base_of<any_executor, AnyExecutor2>::value,+    bool+  >::type operator!=(const AnyExecutor1& a,+      const AnyExecutor2& b) ASIO_NOEXCEPT+  {+    return !static_cast<const any_executor&>(a).equality_helper(b);+  }++  template <typename AnyExecutor>+  friend typename enable_if<+    is_same<AnyExecutor, any_executor>::value,+    bool+  >::type operator!=(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT+  {+    return !!a;+  }++  template <typename AnyExecutor>+  friend typename enable_if<+    is_same<AnyExecutor, any_executor>::value,+    bool+  >::type operator!=(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT+  {+    return !!b;+  }++  template <typename T>+  struct find_convertible_property :+      detail::supportable_properties<+        0, void(SupportableProperties...)>::template+          find_convertible_property<T> {};++  template <typename Property>+  void query(const Property& p,+      typename enable_if<+        is_same<+          typename find_convertible_property<Property>::query_result_type,+          void+        >::value+      >::type* = 0) const+  {+    typedef find_convertible_property<Property> found;+    prop_fns_[found::index].query(0, object_fns_->target(*this),+        &static_cast<const typename found::type&>(p));+  }++  template <typename Property>+  typename find_convertible_property<Property>::query_result_type+  query(const Property& p,+      typename enable_if<+        !is_same<+          typename find_convertible_property<Property>::query_result_type,+          void+        >::value+        &&+        is_reference<+          typename find_convertible_property<Property>::query_result_type+        >::value+      >::type* = 0) const+  {+    typedef find_convertible_property<Property> found;+    typename remove_reference<+      typename found::query_result_type>::type* result = 0;+    prop_fns_[found::index].query(&result, object_fns_->target(*this),+        &static_cast<const typename found::type&>(p));+    return *result;+  }++  template <typename Property>+  typename find_convertible_property<Property>::query_result_type+  query(const Property& p,+      typename enable_if<+        !is_same<+          typename find_convertible_property<Property>::query_result_type,+          void+        >::value+        &&+        is_scalar<+          typename find_convertible_property<Property>::query_result_type+        >::value+      >::type* = 0) const+  {+    typedef find_convertible_property<Property> found;+    typename found::query_result_type result;+    prop_fns_[found::index].query(&result, object_fns_->target(*this),+        &static_cast<const typename found::type&>(p));+    return result;+  }++  template <typename Property>+  typename find_convertible_property<Property>::query_result_type+  query(const Property& p,+      typename enable_if<+        !is_same<+          typename find_convertible_property<Property>::query_result_type,+          void+        >::value+        &&+        !is_reference<+          typename find_convertible_property<Property>::query_result_type+        >::value+        &&+        !is_scalar<+          typename find_convertible_property<Property>::query_result_type+        >::value+      >::type* = 0) const+  {+    typedef find_convertible_property<Property> found;+    typename found::query_result_type* result;+    prop_fns_[found::index].query(&result, object_fns_->target(*this),+        &static_cast<const typename found::type&>(p));+    return *asio::detail::scoped_ptr<+      typename found::query_result_type>(result);+  }++  template <typename T>+  struct find_convertible_requirable_property :+      detail::supportable_properties<+        0, void(SupportableProperties...)>::template+          find_convertible_requirable_property<T> {};++  template <typename Property>+  any_executor require(const Property& p,+      typename enable_if<+        find_convertible_requirable_property<Property>::value+      >::type* = 0) const+  {+    typedef find_convertible_requirable_property<Property> found;+    return prop_fns_[found::index].require(object_fns_->target(*this),+        &static_cast<const typename found::type&>(p));+  }++  template <typename T>+  struct find_convertible_preferable_property :+      detail::supportable_properties<+        0, void(SupportableProperties...)>::template+          find_convertible_preferable_property<T> {};++  template <typename Property>+  any_executor prefer(const Property& p,+      typename enable_if<+        find_convertible_preferable_property<Property>::value+      >::type* = 0) const+  {+    typedef find_convertible_preferable_property<Property> found;+    return prop_fns_[found::index].prefer(object_fns_->target(*this),+        &static_cast<const typename found::type&>(p));+  }++//private:+  template <typename Ex>+  static const prop_fns<any_executor>* prop_fns_table()+  {+    static const prop_fns<any_executor> fns[] =+    {+      {+        &detail::any_executor_base::query_fn<+            Ex, SupportableProperties>,+        &detail::any_executor_base::require_fn<+            any_executor, Ex, SupportableProperties>,+        &detail::any_executor_base::prefer_fn<+            any_executor, Ex, SupportableProperties>+      }...+    };+    return fns;+  }++  const prop_fns<any_executor>* prop_fns_;+};++template <typename... SupportableProperties>+inline void swap(any_executor<SupportableProperties...>& a,+    any_executor<SupportableProperties...>& b) ASIO_NOEXCEPT+{+  return a.swap(b);+}++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS(n) \+  ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_##n++#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1 \+  {  \+    &detail::any_executor_base::query_fn<Ex, T1>, \+    &detail::any_executor_base::require_fn<any_executor, Ex, T1>, \+    &detail::any_executor_base::prefer_fn<any_executor, Ex, T1> \+  }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2 \+  ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1, \+  { \+    &detail::any_executor_base::query_fn<Ex, T2>, \+    &detail::any_executor_base::require_fn<any_executor, Ex, T2>, \+    &detail::any_executor_base::prefer_fn<any_executor, Ex, T2> \+  }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3 \+  ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2, \+  { \+    &detail::any_executor_base::query_fn<Ex, T3>, \+    &detail::any_executor_base::require_fn<any_executor, Ex, T3>, \+    &detail::any_executor_base::prefer_fn<any_executor, Ex, T3> \+  }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4 \+  ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3, \+  { \+    &detail::any_executor_base::query_fn<Ex, T4>, \+    &detail::any_executor_base::require_fn<any_executor, Ex, T4>, \+    &detail::any_executor_base::prefer_fn<any_executor, Ex, T4> \+  }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5 \+  ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4, \+  { \+    &detail::any_executor_base::query_fn<Ex, T5>, \+    &detail::any_executor_base::require_fn<any_executor, Ex, T5>, \+    &detail::any_executor_base::prefer_fn<any_executor, Ex, T5> \+  }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6 \+  ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5, \+  { \+    &detail::any_executor_base::query_fn<Ex, T6>, \+    &detail::any_executor_base::require_fn<any_executor, Ex, T6>, \+    &detail::any_executor_base::prefer_fn<any_executor, Ex, T6> \+  }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7 \+  ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6, \+  { \+    &detail::any_executor_base::query_fn<Ex, T7>, \+    &detail::any_executor_base::require_fn<any_executor, Ex, T7>, \+    &detail::any_executor_base::prefer_fn<any_executor, Ex, T7> \+  }+#define ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_8 \+  ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7, \+  { \+    &detail::any_executor_base::query_fn<Ex, T8>, \+    &detail::any_executor_base::require_fn<any_executor, Ex, T8>, \+    &detail::any_executor_base::prefer_fn<any_executor, Ex, T8> \+  }++#if defined(ASIO_HAS_MOVE)++# define ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS \+  any_executor(any_executor&& other) ASIO_NOEXCEPT \+    : detail::any_executor_base( \+        static_cast<any_executor_base&&>( \+          static_cast<any_executor_base&>(other))), \+      prop_fns_(other.prop_fns_) \+  { \+    other.prop_fns_ = prop_fns_table<void>(); \+  } \+  \+  any_executor(std::nothrow_t, any_executor&& other) ASIO_NOEXCEPT \+    : detail::any_executor_base( \+        static_cast<any_executor_base&&>( \+          static_cast<any_executor_base&>(other))), \+      prop_fns_(other.prop_fns_) \+  { \+    other.prop_fns_ = prop_fns_table<void>(); \+  } \+  \+  any_executor& operator=(any_executor&& other) ASIO_NOEXCEPT \+  { \+    if (this != &other) \+    { \+      prop_fns_ = other.prop_fns_; \+      detail::any_executor_base::operator=( \+          static_cast<detail::any_executor_base&&>( \+            static_cast<detail::any_executor_base&>(other))); \+    } \+    return *this; \+  } \+  /**/+#else // defined(ASIO_HAS_MOVE)++# define ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS++#endif // defined(ASIO_HAS_MOVE)++#define ASIO_PRIVATE_ANY_EXECUTOR_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  class any_executor<ASIO_VARIADIC_TARGS(n)> : \+    public detail::any_executor_base, \+    public detail::any_executor_context< \+      any_executor<ASIO_VARIADIC_TARGS(n)>, \+        typename detail::supportable_properties< \+          0, void(ASIO_VARIADIC_TARGS(n))>::find_context_as_property> \+  { \+  public: \+    any_executor() ASIO_NOEXCEPT \+      : detail::any_executor_base(), \+        prop_fns_(prop_fns_table<void>()) \+    { \+    } \+    \+    any_executor(nullptr_t) ASIO_NOEXCEPT \+      : detail::any_executor_base(), \+        prop_fns_(prop_fns_table<void>()) \+    { \+    } \+    \+    template <ASIO_EXECUTION_EXECUTOR Executor> \+    any_executor(Executor ex, \+        typename enable_if< \+          conditional< \+            !is_same<Executor, any_executor>::value \+              && !is_base_of<detail::any_executor_base, Executor>::value, \+            detail::is_valid_target_executor< \+              Executor, void(ASIO_VARIADIC_TARGS(n))>, \+            false_type \+          >::type::value \+        >::type* = 0) \+      : detail::any_executor_base(ASIO_MOVE_CAST( \+            Executor)(ex), false_type()), \+        prop_fns_(prop_fns_table<Executor>()) \+    { \+    } \+    \+    template <ASIO_EXECUTION_EXECUTOR Executor> \+    any_executor(std::nothrow_t, Executor ex, \+        typename enable_if< \+          conditional< \+            !is_same<Executor, any_executor>::value \+              && !is_base_of<detail::any_executor_base, Executor>::value, \+            detail::is_valid_target_executor< \+              Executor, void(ASIO_VARIADIC_TARGS(n))>, \+            false_type \+          >::type::value \+        >::type* = 0) ASIO_NOEXCEPT \+      : detail::any_executor_base(std::nothrow, \+          ASIO_MOVE_CAST(Executor)(ex), false_type()), \+        prop_fns_(prop_fns_table<Executor>()) \+    { \+      if (this->template target<void>() == 0) \+        prop_fns_ = prop_fns_table<void>(); \+    } \+    \+    any_executor(const any_executor& other) ASIO_NOEXCEPT \+      : detail::any_executor_base( \+          static_cast<const detail::any_executor_base&>(other)), \+        prop_fns_(other.prop_fns_) \+    { \+    } \+    \+    any_executor(std::nothrow_t, \+        const any_executor& other) ASIO_NOEXCEPT \+      : detail::any_executor_base( \+          static_cast<const detail::any_executor_base&>(other)), \+        prop_fns_(other.prop_fns_) \+    { \+      if (this->template target<void>() == 0) \+        prop_fns_ = prop_fns_table<void>(); \+    } \+    \+    any_executor(any_executor<> other) \+      : detail::any_executor_base(ASIO_MOVE_CAST( \+            any_executor<>)(other), true_type()), \+        prop_fns_(prop_fns_table<any_executor<> >()) \+    { \+    } \+    \+    any_executor(std::nothrow_t, any_executor<> other) ASIO_NOEXCEPT \+      : detail::any_executor_base(std::nothrow, \+          ASIO_MOVE_CAST(any_executor<>)(other), true_type()), \+        prop_fns_(prop_fns_table<any_executor<> >()) \+    { \+      if (this->template target<void>() == 0) \+        prop_fns_ = prop_fns_table<void>(); \+    } \+    \+    template <typename OtherAnyExecutor> \+    any_executor(OtherAnyExecutor other, \+        typename enable_if< \+          conditional< \+            !is_same<OtherAnyExecutor, any_executor>::value \+              && is_base_of<detail::any_executor_base, \+                OtherAnyExecutor>::value, \+            typename detail::supportable_properties< \+              0, void(ASIO_VARIADIC_TARGS(n))>::template \+                is_valid_target<OtherAnyExecutor>, \+            false_type \+          >::type::value \+        >::type* = 0) \+      : detail::any_executor_base(ASIO_MOVE_CAST( \+            OtherAnyExecutor)(other), true_type()), \+        prop_fns_(prop_fns_table<OtherAnyExecutor>()) \+    { \+    } \+    \+    template <typename OtherAnyExecutor> \+    any_executor(std::nothrow_t, OtherAnyExecutor other, \+        typename enable_if< \+          conditional< \+            !is_same<OtherAnyExecutor, any_executor>::value \+              && is_base_of<detail::any_executor_base, \+                OtherAnyExecutor>::value, \+            typename detail::supportable_properties< \+              0, void(ASIO_VARIADIC_TARGS(n))>::template \+                is_valid_target<OtherAnyExecutor>, \+            false_type \+          >::type::value \+        >::type* = 0) ASIO_NOEXCEPT \+      : detail::any_executor_base(std::nothrow, \+          ASIO_MOVE_CAST(OtherAnyExecutor)(other), true_type()), \+        prop_fns_(prop_fns_table<OtherAnyExecutor>()) \+    { \+      if (this->template target<void>() == 0) \+        prop_fns_ = prop_fns_table<void>(); \+    } \+    \+    any_executor& operator=(const any_executor& other) ASIO_NOEXCEPT \+    { \+      if (this != &other) \+      { \+        prop_fns_ = other.prop_fns_; \+        detail::any_executor_base::operator=( \+            static_cast<const detail::any_executor_base&>(other)); \+      } \+      return *this; \+    } \+    \+    any_executor& operator=(nullptr_t p) ASIO_NOEXCEPT \+    { \+      prop_fns_ = prop_fns_table<void>(); \+      detail::any_executor_base::operator=(p); \+      return *this; \+    } \+    \+    ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS \+    \+    void swap(any_executor& other) ASIO_NOEXCEPT \+    { \+      if (this != &other) \+      { \+        detail::any_executor_base::swap( \+            static_cast<detail::any_executor_base&>(other)); \+        const prop_fns<any_executor>* tmp_prop_fns = other.prop_fns_; \+        other.prop_fns_ = prop_fns_; \+        prop_fns_ = tmp_prop_fns; \+      } \+    } \+    \+    using detail::any_executor_base::execute; \+    using detail::any_executor_base::target; \+    using detail::any_executor_base::target_type; \+    using detail::any_executor_base::operator unspecified_bool_type; \+    using detail::any_executor_base::operator!; \+    \+    bool equality_helper(const any_executor& other) const ASIO_NOEXCEPT \+    { \+      return any_executor_base::equality_helper(other); \+    } \+    \+    template <typename AnyExecutor1, typename AnyExecutor2> \+    friend typename enable_if< \+      is_base_of<any_executor, AnyExecutor1>::value \+        || is_base_of<any_executor, AnyExecutor2>::value, \+      bool \+    >::type operator==(const AnyExecutor1& a, \+        const AnyExecutor2& b) ASIO_NOEXCEPT \+    { \+      return static_cast<const any_executor&>(a).equality_helper(b); \+    } \+    \+    template <typename AnyExecutor> \+    friend typename enable_if< \+      is_same<AnyExecutor, any_executor>::value, \+      bool \+    >::type operator==(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT \+    { \+      return !a; \+    } \+    \+    template <typename AnyExecutor> \+    friend typename enable_if< \+      is_same<AnyExecutor, any_executor>::value, \+      bool \+    >::type operator==(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT \+    { \+      return !b; \+    } \+    \+    template <typename AnyExecutor1, typename AnyExecutor2> \+    friend typename enable_if< \+      is_base_of<any_executor, AnyExecutor1>::value \+        || is_base_of<any_executor, AnyExecutor2>::value, \+      bool \+    >::type operator!=(const AnyExecutor1& a, \+        const AnyExecutor2& b) ASIO_NOEXCEPT \+    { \+      return !static_cast<const any_executor&>(a).equality_helper(b); \+    } \+    \+    template <typename AnyExecutor> \+    friend typename enable_if< \+      is_same<AnyExecutor, any_executor>::value, \+      bool \+    >::type operator!=(const AnyExecutor& a, nullptr_t) ASIO_NOEXCEPT \+    { \+      return !!a; \+    } \+    \+    template <typename AnyExecutor> \+    friend typename enable_if< \+      is_same<AnyExecutor, any_executor>::value, \+      bool \+    >::type operator!=(nullptr_t, const AnyExecutor& b) ASIO_NOEXCEPT \+    { \+      return !!b; \+    } \+    \+    template <typename T> \+    struct find_convertible_property : \+        detail::supportable_properties< \+          0, void(ASIO_VARIADIC_TARGS(n))>::template \+            find_convertible_property<T> {}; \+    \+    template <typename Property> \+    void query(const Property& p, \+        typename enable_if< \+          is_same< \+            typename find_convertible_property<Property>::query_result_type, \+            void \+          >::value \+        >::type* = 0) const \+    { \+      typedef find_convertible_property<Property> found; \+      prop_fns_[found::index].query(0, object_fns_->target(*this), \+          &static_cast<const typename found::type&>(p)); \+    } \+    \+    template <typename Property> \+    typename find_convertible_property<Property>::query_result_type \+    query(const Property& p, \+        typename enable_if< \+          !is_same< \+            typename find_convertible_property<Property>::query_result_type, \+            void \+          >::value \+          && \+          is_reference< \+            typename find_convertible_property<Property>::query_result_type \+          >::value \+        >::type* = 0) const \+    { \+      typedef find_convertible_property<Property> found; \+      typename remove_reference< \+        typename found::query_result_type>::type* result; \+      prop_fns_[found::index].query(&result, object_fns_->target(*this), \+          &static_cast<const typename found::type&>(p)); \+      return *result; \+    } \+    \+    template <typename Property> \+    typename find_convertible_property<Property>::query_result_type \+    query(const Property& p, \+        typename enable_if< \+          !is_same< \+            typename find_convertible_property<Property>::query_result_type, \+            void \+          >::value \+          && \+          is_scalar< \+            typename find_convertible_property<Property>::query_result_type \+          >::value \+        >::type* = 0) const \+    { \+      typedef find_convertible_property<Property> found; \+      typename found::query_result_type result; \+      prop_fns_[found::index].query(&result, object_fns_->target(*this), \+          &static_cast<const typename found::type&>(p)); \+      return result; \+    } \+    \+    template <typename Property> \+    typename find_convertible_property<Property>::query_result_type \+    query(const Property& p, \+        typename enable_if< \+          !is_same< \+            typename find_convertible_property<Property>::query_result_type, \+            void \+          >::value \+          && \+          !is_reference< \+            typename find_convertible_property<Property>::query_result_type \+          >::value \+          && \+          !is_scalar< \+            typename find_convertible_property<Property>::query_result_type \+          >::value \+        >::type* = 0) const \+    { \+      typedef find_convertible_property<Property> found; \+      typename found::query_result_type* result; \+      prop_fns_[found::index].query(&result, object_fns_->target(*this), \+          &static_cast<const typename found::type&>(p)); \+      return *asio::detail::scoped_ptr< \+        typename found::query_result_type>(result); \+    } \+    \+    template <typename T> \+    struct find_convertible_requirable_property : \+        detail::supportable_properties< \+          0, void(ASIO_VARIADIC_TARGS(n))>::template \+            find_convertible_requirable_property<T> {}; \+    \+    template <typename Property> \+    any_executor require(const Property& p, \+        typename enable_if< \+          find_convertible_requirable_property<Property>::value \+        >::type* = 0) const \+    { \+      typedef find_convertible_requirable_property<Property> found; \+      return prop_fns_[found::index].require(object_fns_->target(*this), \+          &static_cast<const typename found::type&>(p)); \+    } \+    \+    template <typename T> \+    struct find_convertible_preferable_property : \+        detail::supportable_properties< \+          0, void(ASIO_VARIADIC_TARGS(n))>::template \+            find_convertible_preferable_property<T> {}; \+    \+    template <typename Property> \+    any_executor prefer(const Property& p, \+        typename enable_if< \+          find_convertible_preferable_property<Property>::value \+        >::type* = 0) const \+    { \+      typedef find_convertible_preferable_property<Property> found; \+      return prop_fns_[found::index].prefer(object_fns_->target(*this), \+          &static_cast<const typename found::type&>(p)); \+    } \+    \+    template <typename Ex> \+    static const prop_fns<any_executor>* prop_fns_table() \+    { \+      static const prop_fns<any_executor> fns[] = \+      { \+        ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS(n) \+      }; \+      return fns; \+    } \+    \+    const prop_fns<any_executor>* prop_fns_; \+    typedef detail::supportable_properties<0, \+        void(ASIO_VARIADIC_TARGS(n))> supportable_properties_type; \+  }; \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  inline void swap(any_executor<ASIO_VARIADIC_TARGS(n)>& a, \+      any_executor<ASIO_VARIADIC_TARGS(n)>& b) ASIO_NOEXCEPT \+  { \+    return a.swap(b); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_DEF+#undef ASIO_PRIVATE_ANY_EXECUTOR_MOVE_OPS+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_1+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_2+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_3+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_4+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_5+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_6+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_7+#undef ASIO_PRIVATE_ANY_EXECUTOR_PROP_FNS_8++#endif // if defined(ASIO_HAS_VARIADIC_TEMPLATES)++} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename... SupportableProperties>+struct equality_comparable<execution::any_executor<SupportableProperties...> >+{+  static const bool is_valid = true;+  static const bool is_noexcept = true;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <>+struct equality_comparable<execution::any_executor<> >+{+  static const bool is_valid = true;+  static const bool is_noexcept = true;+};++#define ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  struct equality_comparable< \+      execution::any_executor<ASIO_VARIADIC_TARGS(n)> > \+  { \+    static const bool is_valid = true; \+    static const bool is_noexcept = true; \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(+      ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_EQUALITY_COMPARABLE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename F, typename... SupportableProperties>+struct execute_member<execution::any_executor<SupportableProperties...>, F>+{+  static const bool is_valid = true;+  static const bool is_noexcept = false;+  typedef void result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename F>+struct execute_member<execution::any_executor<>, F>+{+  static const bool is_valid = true;+  static const bool is_noexcept = false;+  typedef void result_type;+};++#define ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF(n) \+  template <typename F, ASIO_VARIADIC_TPARAMS(n)> \+  struct execute_member< \+      execution::any_executor<ASIO_VARIADIC_TARGS(n)>, F> \+  { \+    static const bool is_valid = true; \+    static const bool is_noexcept = false; \+    typedef void result_type; \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(+      ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_EXECUTE_MEMBER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Prop, typename... SupportableProperties>+struct query_member<+    execution::any_executor<SupportableProperties...>, Prop,+    typename enable_if<+      execution::detail::supportable_properties<+        0, void(SupportableProperties...)>::template+          find_convertible_property<Prop>::value+    >::type>+{+  static const bool is_valid = true;+  static const bool is_noexcept = false;+  typedef typename execution::detail::supportable_properties<+      0, void(SupportableProperties...)>::template+        find_convertible_property<Prop>::query_result_type result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF(n) \+  template <typename Prop, ASIO_VARIADIC_TPARAMS(n)> \+  struct query_member< \+      execution::any_executor<ASIO_VARIADIC_TARGS(n)>, Prop, \+      typename enable_if< \+        execution::detail::supportable_properties< \+          0, void(ASIO_VARIADIC_TARGS(n))>::template \+            find_convertible_property<Prop>::value \+    >::type> \+  { \+    static const bool is_valid = true; \+    static const bool is_noexcept = false; \+    typedef typename execution::detail::supportable_properties< \+        0, void(ASIO_VARIADIC_TARGS(n))>::template \+          find_convertible_property<Prop>::query_result_type result_type; \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_QUERY_MEMBER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Prop, typename... SupportableProperties>+struct require_member<+    execution::any_executor<SupportableProperties...>, Prop,+    typename enable_if<+      execution::detail::supportable_properties<+        0, void(SupportableProperties...)>::template+          find_convertible_requirable_property<Prop>::value+    >::type>+{+  static const bool is_valid = true;+  static const bool is_noexcept = false;+  typedef execution::any_executor<SupportableProperties...> result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF(n) \+  template <typename Prop, ASIO_VARIADIC_TPARAMS(n)> \+  struct require_member< \+      execution::any_executor<ASIO_VARIADIC_TARGS(n)>, Prop, \+      typename enable_if< \+        execution::detail::supportable_properties< \+          0, void(ASIO_VARIADIC_TARGS(n))>::template \+            find_convertible_requirable_property<Prop>::value \+      >::type> \+  { \+    static const bool is_valid = true; \+    static const bool is_noexcept = false; \+    typedef execution::any_executor<ASIO_VARIADIC_TARGS(n)> result_type; \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(+      ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_REQUIRE_MEMBER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+#endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Prop, typename... SupportableProperties>+struct prefer_member<+    execution::any_executor<SupportableProperties...>, Prop,+    typename enable_if<+      execution::detail::supportable_properties<+        0, void(SupportableProperties...)>::template+          find_convertible_preferable_property<Prop>::value+    >::type>+{+  static const bool is_valid = true;+  static const bool is_noexcept = false;+  typedef execution::any_executor<SupportableProperties...> result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF(n) \+  template <typename Prop, ASIO_VARIADIC_TPARAMS(n)> \+  struct prefer_member< \+      execution::any_executor<ASIO_VARIADIC_TARGS(n)>, Prop, \+      typename enable_if< \+        execution::detail::supportable_properties< \+          0, void(ASIO_VARIADIC_TARGS(n))>::template \+            find_convertible_preferable_property<Prop>::value \+      >::type> \+  { \+    static const bool is_valid = true; \+    static const bool is_noexcept = false; \+    typedef execution::any_executor<ASIO_VARIADIC_TARGS(n)> result_type; \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF)+#undef ASIO_PRIVATE_ANY_EXECUTOR_PREFER_FREE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) #endif // !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)  } // namespace traits
link/modules/asio-standalone/asio/include/asio/execution/bad_executor.hpp view
@@ -2,7 +2,7 @@ // execution/bad_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -28,10 +28,11 @@ { public:   /// Constructor.-  ASIO_DECL bad_executor() noexcept;+  ASIO_DECL bad_executor() ASIO_NOEXCEPT;    /// Obtain message associated with exception.-  ASIO_DECL virtual const char* what() const noexcept;+  ASIO_DECL virtual const char* what() const+    ASIO_NOEXCEPT_OR_NOTHROW; };  } // namespace execution
link/modules/asio-standalone/asio/include/asio/execution/blocking.hpp view
@@ -2,7 +2,7 @@ // execution/blocking.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,7 +17,10 @@  #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/prefer.hpp" #include "asio/query.hpp"@@ -41,9 +44,10 @@ /// behaviour of their execution functions. struct blocking_t {-  /// The blocking_t property applies to executors.+  /// The blocking_t property applies to executors, senders, and schedulers.   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor_v<T>;+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;    /// The top-level blocking_t property cannot be required.   static constexpr bool is_requirable = false;@@ -59,9 +63,11 @@   /// submitted function object.   struct possibly_t   {-    /// The blocking_t::possibly_t property applies to executors.+    /// The blocking_t::possibly_t property applies to executors, senders, and+    /// schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The blocking_t::possibly_t property can be required.     static constexpr bool is_requirable = true;@@ -87,9 +93,11 @@   /// function object.   struct always_t   {-    /// The blocking_t::always_t property applies to executors.+    /// The blocking_t::always_t property applies to executors, senders, and+    /// schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The blocking_t::always_t property can be required.     static constexpr bool is_requirable = true;@@ -115,9 +123,11 @@   /// submitted function object.   struct never_t   {-    /// The blocking_t::never_t property applies to executors.+    /// The blocking_t::never_t property applies to executors, senders, and+    /// schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The blocking_t::never_t property can be required.     static constexpr bool is_requirable = true;@@ -190,8 +200,8 @@  template <typename Executor, typename Function> void blocking_execute(-    Executor&& ex,-    Function&& func);+    ASIO_MOVE_ARG(Executor) ex,+    ASIO_MOVE_ARG(Function) func);  } // namespace blocking_adaptation @@ -199,34 +209,54 @@ struct blocking_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = false;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);   typedef blocking_t polymorphic_query_result_type;    typedef detail::blocking::possibly_t<I> possibly_t;   typedef detail::blocking::always_t<I> always_t;   typedef detail::blocking::never_t<I> never_t; -  constexpr blocking_t()+  ASIO_CONSTEXPR blocking_t()     : value_(-1)   {   } -  constexpr blocking_t(possibly_t)+  ASIO_CONSTEXPR blocking_t(possibly_t)     : value_(0)   {   } -  constexpr blocking_t(always_t)+  ASIO_CONSTEXPR blocking_t(always_t)     : value_(1)   {   } -  constexpr blocking_t(never_t)+  ASIO_CONSTEXPR blocking_t(never_t)     : value_(2)   {   }@@ -238,14 +268,16 @@     struct type     {       template <typename P>-      auto query(P&& p) const+      auto query(ASIO_MOVE_ARG(P) p) const         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().query(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().query(+            ASIO_MOVE_CAST(P)(p))         );     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -260,17 +292,17 @@     struct type     {       template <typename P>-      static constexpr auto query(P&& p)+      static constexpr auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            conditional_t<true, T, P>::query(static_cast<P&&>(p))+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          conditional_t<true, T, P>::query(static_cast<P&&>(p))+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))         )       {-        return T::query(static_cast<P&&>(p));+        return T::query(ASIO_MOVE_CAST(P)(p));       }     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -290,87 +322,88 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, possibly_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, possibly_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, possibly_t>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, always_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::static_query<T, possibly_t>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, always_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, always_t>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, never_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::static_query<T, possibly_t>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::static_query<T, always_t>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, never_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, never_t>::value();   }    template <typename E, typename T = decltype(blocking_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = blocking_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const blocking_t& a, const blocking_t& b)   {     return a.value_ == b.value_;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const blocking_t& a, const blocking_t& b)   {     return a.value_ != b.value_;@@ -378,20 +411,22 @@    struct convertible_from_blocking_t   {-    constexpr convertible_from_blocking_t(blocking_t) {}+    ASIO_CONSTEXPR convertible_from_blocking_t(blocking_t) {}   };    template <typename Executor>-  friend constexpr blocking_t query(+  friend ASIO_CONSTEXPR blocking_t query(       const Executor& ex, convertible_from_blocking_t,-      enable_if_t<+      typename enable_if<         can_query<const Executor&, possibly_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&, blocking_t<>::possibly_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, blocking_t<>::possibly_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, possibly_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, possibly_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -399,19 +434,21 @@   }    template <typename Executor>-  friend constexpr blocking_t query(+  friend ASIO_CONSTEXPR blocking_t query(       const Executor& ex, convertible_from_blocking_t,-      enable_if_t<+      typename enable_if<         !can_query<const Executor&, possibly_t>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_query<const Executor&, always_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&, blocking_t<>::always_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, blocking_t<>::always_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, always_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, always_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -419,22 +456,24 @@   }    template <typename Executor>-  friend constexpr blocking_t query(+  friend ASIO_CONSTEXPR blocking_t query(       const Executor& ex, convertible_from_blocking_t,-      enable_if_t<+      typename enable_if<         !can_query<const Executor&, possibly_t>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !can_query<const Executor&, always_t>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_query<const Executor&, never_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&, blocking_t<>::never_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, blocking_t<>::never_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, never_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, never_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -445,6 +484,10 @@   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(always_t, always);   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(never_t, never); +#if !defined(ASIO_HAS_CONSTEXPR)+  static const blocking_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private:   int value_; };@@ -456,7 +499,12 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>+const blocking_t<I> blocking_t<I>::instance;+#endif++template <int I> const typename blocking_t<I>::possibly_t blocking_t<I>::possibly;  template <int I>@@ -471,15 +519,35 @@ struct possibly_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef blocking_t<I> polymorphic_query_result_type; -  constexpr possibly_t()+  ASIO_CONSTEXPR possibly_t()   {   } @@ -496,77 +564,78 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr possibly_t static_query(-      enable_if_t<+  static ASIO_CONSTEXPR possibly_t static_query(+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::query_free<T, possibly_t>::is_valid-      >* = 0,-      enable_if_t<-        !can_query<T, always_t<I>>::value-      >* = 0,-      enable_if_t<-        !can_query<T, never_t<I>>::value-      >* = 0) noexcept+      >::type* = 0,+      typename enable_if<+        !can_query<T, always_t<I> >::value+      >::type* = 0,+      typename enable_if<+        !can_query<T, never_t<I> >::value+      >::type* = 0) ASIO_NOEXCEPT   {     return possibly_t();   }    template <typename E, typename T = decltype(possibly_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = possibly_t::static_query<E>(); #endif // defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr blocking_t<I> value()+  static ASIO_CONSTEXPR blocking_t<I> value()   {     return possibly_t();   } -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const possibly_t&, const possibly_t&)   {     return true;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const possibly_t&, const possibly_t&)   {     return false;   } -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const possibly_t&, const always_t<I>&)   {     return false;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const possibly_t&, const always_t<I>&)   {     return true;   } -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const possibly_t&, const never_t<I>&)   {     return false;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const possibly_t&, const never_t<I>&)   {     return true;@@ -584,110 +653,129 @@ class adapter { public:-  adapter(int, const Executor& e) noexcept+  adapter(int, const Executor& e) ASIO_NOEXCEPT     : executor_(e)   {   } -  adapter(const adapter& other) noexcept+  adapter(const adapter& other) ASIO_NOEXCEPT     : executor_(other.executor_)   {   } -  adapter(adapter&& other) noexcept-    : executor_(static_cast<Executor&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+  adapter(adapter&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(Executor)(other.executor_))   {   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    template <int I>-  static constexpr always_t<I> query(blocking_t<I>) noexcept+  static ASIO_CONSTEXPR always_t<I> query(+      blocking_t<I>) ASIO_NOEXCEPT   {     return always_t<I>();   }    template <int I>-  static constexpr always_t<I> query(possibly_t<I>) noexcept+  static ASIO_CONSTEXPR always_t<I> query(+      possibly_t<I>) ASIO_NOEXCEPT   {     return always_t<I>();   }    template <int I>-  static constexpr always_t<I> query(always_t<I>) noexcept+  static ASIO_CONSTEXPR always_t<I> query(+      always_t<I>) ASIO_NOEXCEPT   {     return always_t<I>();   }    template <int I>-  static constexpr always_t<I> query(never_t<I>) noexcept+  static ASIO_CONSTEXPR always_t<I> query(+      never_t<I>) ASIO_NOEXCEPT   {     return always_t<I>();   }    template <typename Property>-  enable_if_t<+  typename enable_if<     can_query<const Executor&, Property>::value,-    query_result_t<const Executor&, Property>-  > query(const Property& p) const-    noexcept(is_nothrow_query<const Executor&, Property>::value)+    typename query_result<const Executor&, Property>::type+  >::type query(const Property& p) const+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, Property>::value))   {     return asio::query(executor_, p);   }    template <int I>-  enable_if_t<-    can_require<const Executor&, possibly_t<I>>::value,-    require_result_t<const Executor&, possibly_t<I>>-  > require(possibly_t<I>) const noexcept+  typename enable_if<+    can_require<const Executor&, possibly_t<I> >::value,+    typename require_result<const Executor&, possibly_t<I> >::type+  >::type require(possibly_t<I>) const ASIO_NOEXCEPT   {     return asio::require(executor_, possibly_t<I>());   }    template <int I>-  enable_if_t<-    can_require<const Executor&, never_t<I>>::value,-    require_result_t<const Executor&, never_t<I>>-  > require(never_t<I>) const noexcept+  typename enable_if<+    can_require<const Executor&, never_t<I> >::value,+    typename require_result<const Executor&, never_t<I> >::type+  >::type require(never_t<I>) const ASIO_NOEXCEPT   {     return asio::require(executor_, never_t<I>());   }    template <typename Property>-  enable_if_t<+  typename enable_if<     can_require<const Executor&, Property>::value,-    adapter<decay_t<require_result_t<const Executor&, Property>>>-  > require(const Property& p) const-    noexcept(is_nothrow_require<const Executor&, Property>::value)+    adapter<typename decay<+      typename require_result<const Executor&, Property>::type+    >::type>+  >::type require(const Property& p) const+    ASIO_NOEXCEPT_IF((+      is_nothrow_require<const Executor&, Property>::value))   {-    return adapter<decay_t<require_result_t<const Executor&, Property>>>(-        0, asio::require(executor_, p));+    return adapter<typename decay<+      typename require_result<const Executor&, Property>::type+        >::type>(0, asio::require(executor_, p));   }    template <typename Property>-  enable_if_t<+  typename enable_if<     can_prefer<const Executor&, Property>::value,-    adapter<decay_t<prefer_result_t<const Executor&, Property>>>-  > prefer(const Property& p) const-    noexcept(is_nothrow_prefer<const Executor&, Property>::value)+    adapter<typename decay<+      typename prefer_result<const Executor&, Property>::type+    >::type>+  >::type prefer(const Property& p) const+    ASIO_NOEXCEPT_IF((+      is_nothrow_prefer<const Executor&, Property>::value))   {-    return adapter<decay_t<prefer_result_t<const Executor&, Property>>>(-        0, asio::prefer(executor_, p));+    return adapter<typename decay<+      typename prefer_result<const Executor&, Property>::type+        >::type>(0, asio::prefer(executor_, p));   }    template <typename Function>-  enable_if_t<+  typename enable_if<+#if defined(ASIO_NO_DEPRECATED)     traits::execute_member<const Executor&, Function>::is_valid-  > execute(Function&& f) const+#else // defined(ASIO_NO_DEPRECATED)+    execution::can_execute<const Executor&, Function>::value+#endif // defined(ASIO_NO_DEPRECATED)+  >::type execute(ASIO_MOVE_ARG(Function) f) const   {     blocking_adaptation::blocking_execute(-        executor_, static_cast<Function&&>(f));+        executor_, ASIO_MOVE_CAST(Function)(f));   } -  friend bool operator==(const adapter& a, const adapter& b) noexcept+  friend bool operator==(const adapter& a, const adapter& b) ASIO_NOEXCEPT   {     return a.executor_ == b.executor_;   } -  friend bool operator!=(const adapter& a, const adapter& b) noexcept+  friend bool operator!=(const adapter& a, const adapter& b) ASIO_NOEXCEPT   {     return a.executor_ != b.executor_;   }@@ -700,15 +788,35 @@ struct always_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);   typedef blocking_t<I> polymorphic_query_result_type; -  constexpr always_t()+  ASIO_CONSTEXPR always_t()   {   } @@ -725,54 +833,57 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(always_t::static_query<E>())>-  static constexpr const T static_query_v = always_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = always_t::static_query<E>(); #endif // defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr blocking_t<I> value()+  static ASIO_CONSTEXPR blocking_t<I> value()   {     return always_t();   } -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const always_t&, const always_t&)   {     return true;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const always_t&, const always_t&)   {     return false;   } -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const always_t&, const possibly_t<I>&)   {     return false;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const always_t&, const possibly_t<I>&)   {     return true;   } -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const always_t&, const never_t<I>&)   {     return false;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const always_t&, const never_t<I>&)   {     return true;@@ -781,15 +892,15 @@   template <typename Executor>   friend adapter<Executor> require(       const Executor& e, const always_t&,-      enable_if_t<+      typename enable_if<         is_executor<Executor>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_require<           const Executor&,           blocking_adaptation::allowed_t<0>         >::is_valid-      >* = 0)+      >::type* = 0)   {     return adapter<Executor>(0, e);   }@@ -806,15 +917,35 @@ struct never_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef blocking_t<I> polymorphic_query_result_type; -  constexpr never_t()+  ASIO_CONSTEXPR never_t()   {   } @@ -831,51 +962,58 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(never_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = never_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr blocking_t<I> value()+  static ASIO_CONSTEXPR blocking_t<I> value()   {     return never_t();   } -  friend constexpr bool operator==(const never_t&, const never_t&)+  friend ASIO_CONSTEXPR bool operator==(+      const never_t&, const never_t&)   {     return true;   } -  friend constexpr bool operator!=(const never_t&, const never_t&)+  friend ASIO_CONSTEXPR bool operator!=(+      const never_t&, const never_t&)   {     return false;   } -  friend constexpr bool operator==(const never_t&, const possibly_t<I>&)+  friend ASIO_CONSTEXPR bool operator==(+      const never_t&, const possibly_t<I>&)   {     return false;   } -  friend constexpr bool operator!=(const never_t&, const possibly_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const never_t&, const possibly_t<I>&)   {     return true;   } -  friend constexpr bool operator==(const never_t&, const always_t<I>&)+  friend ASIO_CONSTEXPR bool operator==(+      const never_t&, const always_t<I>&)   {     return false;   } -  friend constexpr bool operator!=(const never_t&, const always_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const never_t&, const always_t<I>&)   {     return true;   }@@ -892,7 +1030,11 @@  typedef detail::blocking_t<> blocking_t; -ASIO_INLINE_VARIABLE constexpr blocking_t blocking;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr blocking_t blocking;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const blocking_t& blocking = blocking_t::instance; }+#endif  } // namespace execution @@ -900,25 +1042,81 @@  template <typename T> struct is_applicable_property<T, execution::blocking_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::blocking_t::possibly_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::blocking_t::always_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::blocking_t::never_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { }; @@ -930,42 +1128,42 @@  template <typename T> struct query_free_default<T, execution::blocking_t,-  enable_if_t<+  typename enable_if<     can_query<T, execution::blocking_t::possibly_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::blocking_t::possibly_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::blocking_t::possibly_t>::value));    typedef execution::blocking_t result_type; };  template <typename T> struct query_free_default<T, execution::blocking_t,-  enable_if_t<+  typename enable_if<     !can_query<T, execution::blocking_t::possibly_t>::value       && can_query<T, execution::blocking_t::always_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::blocking_t::always_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::blocking_t::always_t>::value));    typedef execution::blocking_t result_type; };  template <typename T> struct query_free_default<T, execution::blocking_t,-  enable_if_t<+  typename enable_if<     !can_query<T, execution::blocking_t::possibly_t>::value       && !can_query<T, execution::blocking_t::always_t>::value       && can_query<T, execution::blocking_t::never_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::blocking_t::never_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::blocking_t::never_t>::value));    typedef execution::blocking_t result_type; };@@ -977,18 +1175,18 @@  template <typename T> struct static_query<T, execution::blocking_t,-  enable_if_t<+  typename enable_if<     execution::detail::blocking_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::blocking_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::blocking_t::query_static_constexpr_member<T>::value();   }@@ -996,21 +1194,21 @@  template <typename T> struct static_query<T, execution::blocking_t,-  enable_if_t<+  typename enable_if<     !execution::detail::blocking_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::blocking_t<0>::         query_member<T>::is_valid       && traits::static_query<T, execution::blocking_t::possibly_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::blocking_t::possibly_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T, execution::blocking_t::possibly_t>::value();   }@@ -1018,22 +1216,22 @@  template <typename T> struct static_query<T, execution::blocking_t,-  enable_if_t<+  typename enable_if<     !execution::detail::blocking_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::blocking_t<0>::         query_member<T>::is_valid       && !traits::static_query<T, execution::blocking_t::possibly_t>::is_valid       && traits::static_query<T, execution::blocking_t::always_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::blocking_t::always_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T, execution::blocking_t::always_t>::value();   }@@ -1041,7 +1239,7 @@  template <typename T> struct static_query<T, execution::blocking_t,-  enable_if_t<+  typename enable_if<     !execution::detail::blocking_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::blocking_t<0>::@@ -1049,15 +1247,15 @@       && !traits::static_query<T, execution::blocking_t::possibly_t>::is_valid       && !traits::static_query<T, execution::blocking_t::always_t>::is_valid       && traits::static_query<T, execution::blocking_t::never_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::blocking_t::never_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T, execution::blocking_t::never_t>::value();   }@@ -1065,18 +1263,18 @@  template <typename T> struct static_query<T, execution::blocking_t::possibly_t,-  enable_if_t<+  typename enable_if<     execution::detail::blocking::possibly_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::blocking::possibly_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::blocking::possibly_t<0>::       query_static_constexpr_member<T>::value();@@ -1085,7 +1283,7 @@  template <typename T> struct static_query<T, execution::blocking_t::possibly_t,-  enable_if_t<+  typename enable_if<     !execution::detail::blocking::possibly_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::blocking::possibly_t<0>::@@ -1093,14 +1291,14 @@       && !traits::query_free<T, execution::blocking_t::possibly_t>::is_valid       && !can_query<T, execution::blocking_t::always_t>::value       && !can_query<T, execution::blocking_t::never_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef execution::blocking_t::possibly_t result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return result_type();   }@@ -1108,18 +1306,18 @@  template <typename T> struct static_query<T, execution::blocking_t::always_t,-  enable_if_t<+  typename enable_if<     execution::detail::blocking::always_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::blocking::always_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::blocking::always_t<0>::       query_static_constexpr_member<T>::value();@@ -1128,18 +1326,18 @@  template <typename T> struct static_query<T, execution::blocking_t::never_t,-  enable_if_t<+  typename enable_if<     execution::detail::blocking::never_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::blocking::never_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::blocking::never_t<0>::       query_static_constexpr_member<T>::value();@@ -1149,21 +1347,61 @@ #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::blocking_t::possibly_t,+  typename enable_if<+    static_query<T, execution::blocking_t::possibly_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::blocking_t::possibly_t>::result_type,+        execution::blocking_t::possibly_t>::value));+};++template <typename T>+struct static_require<T, execution::blocking_t::always_t,+  typename enable_if<+    static_query<T, execution::blocking_t::always_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::blocking_t::always_t>::result_type,+        execution::blocking_t::always_t>::value));+};++template <typename T>+struct static_require<T, execution::blocking_t::never_t,+  typename enable_if<+    static_query<T, execution::blocking_t::never_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::blocking_t::never_t>::result_type,+        execution::blocking_t::never_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)+ #if !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)  template <typename T> struct require_free_default<T, execution::blocking_t::always_t,-  enable_if_t<-    is_same<T, decay_t<T>>::value+  typename enable_if<+    is_same<T, typename decay<T>::type>::value       && execution::is_executor<T>::value       && traits::static_require<           const T&,           execution::detail::blocking_adaptation::allowed_t<0>         >::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef execution::detail::blocking::adapter<T> result_type; }; @@ -1173,10 +1411,10 @@  template <typename Executor> struct equality_comparable<-  execution::detail::blocking::adapter<Executor>>+  execution::detail::blocking::adapter<Executor> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); };  #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -1187,8 +1425,8 @@ struct execute_member<   execution::detail::blocking::adapter<Executor>, Function> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; }; @@ -1199,13 +1437,13 @@ template <typename Executor, int I> struct query_static_constexpr_member<   execution::detail::blocking::adapter<Executor>,-  execution::detail::blocking_t<I>>+  execution::detail::blocking_t<I> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef execution::blocking_t::always_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -1214,13 +1452,13 @@ template <typename Executor, int I> struct query_static_constexpr_member<   execution::detail::blocking::adapter<Executor>,-  execution::detail::blocking::always_t<I>>+  execution::detail::blocking::always_t<I> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef execution::blocking_t::always_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -1229,13 +1467,13 @@ template <typename Executor, int I> struct query_static_constexpr_member<   execution::detail::blocking::adapter<Executor>,-  execution::detail::blocking::possibly_t<I>>+  execution::detail::blocking::possibly_t<I> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef execution::blocking_t::always_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -1244,13 +1482,13 @@ template <typename Executor, int I> struct query_static_constexpr_member<   execution::detail::blocking::adapter<Executor>,-  execution::detail::blocking::never_t<I>>+  execution::detail::blocking::never_t<I> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef execution::blocking_t::always_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -1263,14 +1501,14 @@ template <typename Executor, typename Property> struct query_member<   execution::detail::blocking::adapter<Executor>, Property,-  enable_if_t<+  typename enable_if<     can_query<const Executor&, Property>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<Executor, Property>::value;-  typedef query_result_t<Executor, Property> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_query<Executor, Property>::value));+  typedef typename query_result<Executor, Property>::type result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -1281,52 +1519,53 @@ struct require_member<   execution::detail::blocking::adapter<Executor>,   execution::detail::blocking::possibly_t<I>,-  enable_if_t<+  typename enable_if<     can_require<       const Executor&,       execution::detail::blocking::possibly_t<I>     >::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_require<const Executor&,-      execution::detail::blocking::possibly_t<I>>::value;-  typedef require_result_t<const Executor&,-    execution::detail::blocking::possibly_t<I>> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_require<const Executor&,+        execution::detail::blocking::possibly_t<I> >::value));+  typedef typename require_result<const Executor&,+    execution::detail::blocking::possibly_t<I> >::type result_type; };  template <typename Executor, int I> struct require_member<   execution::detail::blocking::adapter<Executor>,   execution::detail::blocking::never_t<I>,-  enable_if_t<+  typename enable_if<     can_require<       const Executor&,       execution::detail::blocking::never_t<I>     >::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_require<const Executor&,-      execution::detail::blocking::never_t<I>>::value;-  typedef require_result_t<const Executor&,-    execution::detail::blocking::never_t<I>> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_require<const Executor&,+        execution::detail::blocking::never_t<I> >::value));+  typedef typename require_result<const Executor&,+    execution::detail::blocking::never_t<I> >::type result_type; };  template <typename Executor, typename Property> struct require_member<   execution::detail::blocking::adapter<Executor>, Property,-  enable_if_t<+  typename enable_if<     can_require<const Executor&, Property>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_require<Executor, Property>::value;-  typedef execution::detail::blocking::adapter<-    decay_t<require_result_t<Executor, Property>>> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_require<Executor, Property>::value));+  typedef execution::detail::blocking::adapter<typename decay<+    typename require_result<Executor, Property>::type+      >::type> result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -1336,15 +1575,16 @@ template <typename Executor, typename Property> struct prefer_member<   execution::detail::blocking::adapter<Executor>, Property,-  enable_if_t<+  typename enable_if<     can_prefer<const Executor&, Property>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_prefer<Executor, Property>::value;-  typedef execution::detail::blocking::adapter<-    decay_t<prefer_result_t<Executor, Property>>> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_prefer<Executor, Property>::value));+  typedef execution::detail::blocking::adapter<typename decay<+    typename prefer_result<Executor, Property>::type+      >::type> result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
link/modules/asio-standalone/asio/include/asio/execution/blocking_adaptation.hpp view
@@ -2,7 +2,7 @@ // execution/blocking_adaptation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,7 +19,10 @@ #include "asio/detail/event.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/prefer.hpp" #include "asio/query.hpp"@@ -44,9 +47,11 @@ /// allowed in order to apply the blocking_adaptation_t::allowed_t property. struct blocking_adaptation_t {-  /// The blocking_adaptation_t property applies to executors.+  /// The blocking_adaptation_t property applies to executors, senders, and+  /// schedulers.   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor_v<T>;+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;    /// The top-level blocking_adaptation_t property cannot be required.   static constexpr bool is_requirable = false;@@ -60,9 +65,11 @@   /// A sub-property that indicates that automatic adaptation is not allowed.   struct disallowed_t   {-    /// The blocking_adaptation_t::disallowed_t property applies to executors.+    /// The blocking_adaptation_t::disallowed_t property applies to executors,+    /// senders, and schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The blocking_adaptation_t::disallowed_t property can be required.     static constexpr bool is_requirable = true;@@ -86,9 +93,11 @@   /// A sub-property that indicates that automatic adaptation is allowed.   struct allowed_t   {-    /// The blocking_adaptation_t::allowed_t property applies to executors.+    /// The blocking_adaptation_t::allowed_t property applies to executors,+    /// senders, and schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The blocking_adaptation_t::allowed_t property can be required.     static constexpr bool is_requirable = true;@@ -155,28 +164,48 @@ struct blocking_adaptation_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = false;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);   typedef blocking_adaptation_t polymorphic_query_result_type;    typedef detail::blocking_adaptation::disallowed_t<I> disallowed_t;   typedef detail::blocking_adaptation::allowed_t<I> allowed_t; -  constexpr blocking_adaptation_t()+  ASIO_CONSTEXPR blocking_adaptation_t()     : value_(-1)   {   } -  constexpr blocking_adaptation_t(disallowed_t)+  ASIO_CONSTEXPR blocking_adaptation_t(disallowed_t)     : value_(0)   {   } -  constexpr blocking_adaptation_t(allowed_t)+  ASIO_CONSTEXPR blocking_adaptation_t(allowed_t)     : value_(1)   {   }@@ -188,14 +217,16 @@     struct type     {       template <typename P>-      auto query(P&& p) const+      auto query(ASIO_MOVE_ARG(P) p) const         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().query(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().query(+            ASIO_MOVE_CAST(P)(p))         );     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -210,17 +241,17 @@     struct type     {       template <typename P>-      static constexpr auto query(P&& p)+      static constexpr auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            conditional_t<true, T, P>::query(static_cast<P&&>(p))+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          conditional_t<true, T, P>::query(static_cast<P&&>(p))+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))         )       {-        return T::query(static_cast<P&&>(p));+        return T::query(ASIO_MOVE_CAST(P)(p));       }     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -240,64 +271,66 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, disallowed_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, disallowed_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, disallowed_t>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, allowed_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::static_query<T, disallowed_t>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, allowed_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, allowed_t>::value();   }    template <typename E,       typename T = decltype(blocking_adaptation_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = blocking_adaptation_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const blocking_adaptation_t& a, const blocking_adaptation_t& b)   {     return a.value_ == b.value_;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const blocking_adaptation_t& a, const blocking_adaptation_t& b)   {     return a.value_ != b.value_;@@ -305,24 +338,26 @@    struct convertible_from_blocking_adaptation_t   {-    constexpr convertible_from_blocking_adaptation_t(+    ASIO_CONSTEXPR convertible_from_blocking_adaptation_t(         blocking_adaptation_t)     {     }   };    template <typename Executor>-  friend constexpr blocking_adaptation_t query(+  friend ASIO_CONSTEXPR blocking_adaptation_t query(       const Executor& ex, convertible_from_blocking_adaptation_t,-      enable_if_t<+      typename enable_if<         can_query<const Executor&, disallowed_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&,-        blocking_adaptation_t<>::disallowed_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&,+        blocking_adaptation_t<>::disallowed_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, disallowed_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, disallowed_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -330,20 +365,22 @@   }    template <typename Executor>-  friend constexpr blocking_adaptation_t query(+  friend ASIO_CONSTEXPR blocking_adaptation_t query(       const Executor& ex, convertible_from_blocking_adaptation_t,-      enable_if_t<+      typename enable_if<         !can_query<const Executor&, disallowed_t>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_query<const Executor&, allowed_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&,-        blocking_adaptation_t<>::allowed_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&,+        blocking_adaptation_t<>::allowed_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, allowed_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, allowed_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -353,6 +390,10 @@   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(disallowed_t, disallowed);   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(allowed_t, allowed); +#if !defined(ASIO_HAS_CONSTEXPR)+  static const blocking_adaptation_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private:   int value_; };@@ -364,7 +405,12 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>+const blocking_adaptation_t<I> blocking_adaptation_t<I>::instance;+#endif++template <int I> const typename blocking_adaptation_t<I>::disallowed_t blocking_adaptation_t<I>::disallowed; @@ -378,15 +424,35 @@ struct disallowed_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef blocking_adaptation_t<I> polymorphic_query_result_type; -  constexpr disallowed_t()+  ASIO_CONSTEXPR disallowed_t()   {   } @@ -405,62 +471,55 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr disallowed_t static_query(-      enable_if_t<+  static ASIO_CONSTEXPR disallowed_t static_query(+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::query_free<T, disallowed_t>::is_valid-      >* = 0,-      enable_if_t<-        !can_query<T, allowed_t<I>>::value-      >* = 0) noexcept+      >::type* = 0,+      typename enable_if<+        !can_query<T, allowed_t<I> >::value+      >::type* = 0) ASIO_NOEXCEPT   {     return disallowed_t();   }    template <typename E, typename T = decltype(disallowed_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = disallowed_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr blocking_adaptation_t<I> value()+  static ASIO_CONSTEXPR blocking_adaptation_t<I> value()   {     return disallowed_t();   } -  friend constexpr bool operator==(const disallowed_t&, const disallowed_t&)+  friend ASIO_CONSTEXPR bool operator==(+      const disallowed_t&, const disallowed_t&)   {     return true;   } -  friend constexpr bool operator!=(const disallowed_t&, const disallowed_t&)-  {-    return false;-  }--  friend constexpr bool operator==(const disallowed_t&, const allowed_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const disallowed_t&, const disallowed_t&)   {     return false;   }--  friend constexpr bool operator!=(const disallowed_t&, const allowed_t<I>&)-  {-    return true;-  } };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -470,134 +529,117 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -template <typename>-struct is_blocking_adaptation_t : false_type-{-};--template <int I>-struct is_blocking_adaptation_t<blocking_adaptation_t<I>> : true_type-{-};--template <typename>-struct is_allowed_t : false_type-{-};--template <int I>-struct is_allowed_t<allowed_t<I>> : true_type-{-};--template <typename>-struct is_disallowed_t : false_type-{-};--template <int I>-struct is_disallowed_t<disallowed_t<I>> : true_type-{-};- template <typename Executor> class adapter { public:-  adapter(int, const Executor& e) noexcept+  adapter(int, const Executor& e) ASIO_NOEXCEPT     : executor_(e)   {   } -  adapter(const adapter& other) noexcept+  adapter(const adapter& other) ASIO_NOEXCEPT     : executor_(other.executor_)   {   } -  adapter(adapter&& other) noexcept-    : executor_(static_cast<Executor&&>(other.executor_))+#if defined(ASIO_HAS_MOVE)+  adapter(adapter&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(Executor)(other.executor_))   {   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    template <int I>-  static constexpr allowed_t<I> query(blocking_adaptation_t<I>) noexcept+  static ASIO_CONSTEXPR allowed_t<I> query(+      blocking_adaptation_t<I>) ASIO_NOEXCEPT   {     return allowed_t<I>();   }    template <int I>-  static constexpr allowed_t<I> query(allowed_t<I>) noexcept+  static ASIO_CONSTEXPR allowed_t<I> query(+      allowed_t<I>) ASIO_NOEXCEPT   {     return allowed_t<I>();   }    template <int I>-  static constexpr allowed_t<I> query(disallowed_t<I>) noexcept+  static ASIO_CONSTEXPR allowed_t<I> query(+      disallowed_t<I>) ASIO_NOEXCEPT   {     return allowed_t<I>();   }    template <typename Property>-  enable_if_t<-    can_query<const Executor&, Property>::value-      && !is_blocking_adaptation_t<Property>::value-      && !is_allowed_t<Property>::value-      && !is_disallowed_t<Property>::value,-    query_result_t<const Executor&, Property>-  > query(const Property& p) const-    noexcept(is_nothrow_query<const Executor&, Property>::value)+  typename enable_if<+    can_query<const Executor&, Property>::value,+    typename query_result<const Executor&, Property>::type+  >::type query(const Property& p) const+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, Property>::value))   {     return asio::query(executor_, p);   }    template <int I>-  Executor require(disallowed_t<I>) const noexcept+  Executor require(disallowed_t<I>) const ASIO_NOEXCEPT   {     return executor_;   }    template <typename Property>-  enable_if_t<-    can_require<const Executor&, Property>::value-      && !is_blocking_adaptation_t<Property>::value-      && !is_allowed_t<Property>::value-      && !is_disallowed_t<Property>::value,-    adapter<decay_t<require_result_t<const Executor&, Property>>>-  > require(const Property& p) const-    noexcept(is_nothrow_require<const Executor&, Property>::value)+  typename enable_if<+    can_require<const Executor&, Property>::value,+    adapter<typename decay<+      typename require_result<const Executor&, Property>::type+    >::type>+  >::type require(const Property& p) const+    ASIO_NOEXCEPT_IF((+      is_nothrow_require<const Executor&, Property>::value))   {-    return adapter<decay_t<require_result_t<const Executor&, Property>>>(-        0, asio::require(executor_, p));+    return adapter<typename decay<+      typename require_result<const Executor&, Property>::type+        >::type>(0, asio::require(executor_, p));   }    template <typename Property>-  enable_if_t<-    can_prefer<const Executor&, Property>::value-      && !is_blocking_adaptation_t<Property>::value-      && !is_allowed_t<Property>::value-      && !is_disallowed_t<Property>::value,-    adapter<decay_t<prefer_result_t<const Executor&, Property>>>-  > prefer(const Property& p) const-    noexcept(is_nothrow_prefer<const Executor&, Property>::value)+  typename enable_if<+    can_prefer<const Executor&, Property>::value,+    adapter<typename decay<+      typename prefer_result<const Executor&, Property>::type+    >::type>+  >::type prefer(const Property& p) const+    ASIO_NOEXCEPT_IF((+      is_nothrow_prefer<const Executor&, Property>::value))   {-    return adapter<decay_t<prefer_result_t<const Executor&, Property>>>(-        0, asio::prefer(executor_, p));+    return adapter<typename decay<+      typename prefer_result<const Executor&, Property>::type+        >::type>(0, asio::prefer(executor_, p));   }    template <typename Function>-  enable_if_t<+  typename enable_if<+#if defined(ASIO_NO_DEPRECATED)     traits::execute_member<const Executor&, Function>::is_valid-  > execute(Function&& f) const+#else // defined(ASIO_NO_DEPRECATED)+    execution::can_execute<const Executor&, Function>::value+#endif // defined(ASIO_NO_DEPRECATED)+  >::type execute(ASIO_MOVE_ARG(Function) f) const   {-    executor_.execute(static_cast<Function&&>(f));+#if defined(ASIO_NO_DEPRECATED)+    executor_.execute(ASIO_MOVE_CAST(Function)(f));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(executor_, ASIO_MOVE_CAST(Function)(f));+#endif // defined(ASIO_NO_DEPRECATED)   } -  friend bool operator==(const adapter& a, const adapter& b) noexcept+  friend bool operator==(const adapter& a, const adapter& b) ASIO_NOEXCEPT   {     return a.executor_ == b.executor_;   } -  friend bool operator!=(const adapter& a, const adapter& b) noexcept+  friend bool operator!=(const adapter& a, const adapter& b) ASIO_NOEXCEPT   {     return a.executor_ != b.executor_;   }@@ -610,15 +652,35 @@ struct allowed_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);   typedef blocking_adaptation_t<I> polymorphic_query_result_type; -  constexpr allowed_t()+  ASIO_CONSTEXPR allowed_t()   {   } @@ -637,49 +699,44 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(allowed_t::static_query<E>())>-  static constexpr const T static_query_v = allowed_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = allowed_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr blocking_adaptation_t<I> value()+  static ASIO_CONSTEXPR blocking_adaptation_t<I> value()   {     return allowed_t();   } -  friend constexpr bool operator==(const allowed_t&, const allowed_t&)+  friend ASIO_CONSTEXPR bool operator==(+      const allowed_t&, const allowed_t&)   {     return true;   } -  friend constexpr bool operator!=(const allowed_t&, const allowed_t&)-  {-    return false;-  }--  friend constexpr bool operator==(const allowed_t&, const disallowed_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const allowed_t&, const allowed_t&)   {     return false;   } -  friend constexpr bool operator!=(const allowed_t&, const disallowed_t<I>&)-  {-    return true;-  }-   template <typename Executor>   friend adapter<Executor> require(       const Executor& e, const allowed_t&,-      enable_if_t<+      typename enable_if<         is_executor<Executor>::value-      >* = 0)+      >::type* = 0)   {     return adapter<Executor>(0, e);   }@@ -697,17 +754,21 @@ { public:   template <typename F>-  blocking_execute_state(F&& f)-    : func_(static_cast<F&&>(f)),+  blocking_execute_state(ASIO_MOVE_ARG(F) f)+    : func_(ASIO_MOVE_CAST(F)(f)),       is_complete_(false)   {   }    template <typename Executor>-  void execute_and_wait(Executor&& ex)+  void execute_and_wait(ASIO_MOVE_ARG(Executor) ex)   {     handler h = { this };+#if defined(ASIO_NO_DEPRECATED)     ex.execute(h);+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(ASIO_MOVE_CAST(Executor)(ex), h);+#endif // defined(ASIO_NO_DEPRECATED)     asio::detail::mutex::scoped_lock lock(mutex_);     while (!is_complete_)       event_.wait(lock);@@ -744,11 +805,11 @@  template <typename Executor, typename Function> void blocking_execute(-    Executor&& ex,-    Function&& func)+    ASIO_MOVE_ARG(Executor) ex,+    ASIO_MOVE_ARG(Function) func) {-  typedef decay_t<Function> func_t;-  blocking_execute_state<func_t> state(static_cast<Function&&>(func));+  typedef typename decay<Function>::type func_t;+  blocking_execute_state<func_t> state(ASIO_MOVE_CAST(Function)(func));   state.execute_and_wait(ex); } @@ -757,7 +818,12 @@  typedef detail::blocking_adaptation_t<> blocking_adaptation_t; -ASIO_INLINE_VARIABLE constexpr blocking_adaptation_t blocking_adaptation;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr blocking_adaptation_t blocking_adaptation;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const blocking_adaptation_t&+  blocking_adaptation = blocking_adaptation_t::instance; }+#endif  } // namespace execution @@ -765,19 +831,61 @@  template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t::disallowed_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::blocking_adaptation_t::allowed_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { }; @@ -789,27 +897,27 @@  template <typename T> struct query_free_default<T, execution::blocking_adaptation_t,-  enable_if_t<+  typename enable_if<     can_query<T, execution::blocking_adaptation_t::disallowed_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::blocking_adaptation_t::disallowed_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = (is_nothrow_query<T,+      execution::blocking_adaptation_t::disallowed_t>::value));    typedef execution::blocking_adaptation_t result_type; };  template <typename T> struct query_free_default<T, execution::blocking_adaptation_t,-  enable_if_t<+  typename enable_if<     !can_query<T, execution::blocking_adaptation_t::disallowed_t>::value       && can_query<T, execution::blocking_adaptation_t::allowed_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::blocking_adaptation_t::allowed_t>::value));    typedef execution::blocking_adaptation_t result_type; };@@ -821,18 +929,18 @@  template <typename T> struct static_query<T, execution::blocking_adaptation_t,-  enable_if_t<+  typename enable_if<     execution::detail::blocking_adaptation_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::blocking_adaptation_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::blocking_adaptation_t<0>::       query_static_constexpr_member<T>::value();@@ -841,22 +949,22 @@  template <typename T> struct static_query<T, execution::blocking_adaptation_t,-  enable_if_t<+  typename enable_if<     !execution::detail::blocking_adaptation_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::blocking_adaptation_t<0>::         query_member<T>::is_valid       && traits::static_query<T,         execution::blocking_adaptation_t::disallowed_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::blocking_adaptation_t::disallowed_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T,         execution::blocking_adaptation_t::disallowed_t>::value();@@ -865,7 +973,7 @@  template <typename T> struct static_query<T, execution::blocking_adaptation_t,-  enable_if_t<+  typename enable_if<     !execution::detail::blocking_adaptation_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::blocking_adaptation_t<0>::@@ -874,15 +982,15 @@         execution::blocking_adaptation_t::disallowed_t>::is_valid       && traits::static_query<T,         execution::blocking_adaptation_t::allowed_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::blocking_adaptation_t::allowed_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T,         execution::blocking_adaptation_t::allowed_t>::value();@@ -891,18 +999,18 @@  template <typename T> struct static_query<T, execution::blocking_adaptation_t::disallowed_t,-  enable_if_t<+  typename enable_if<     execution::detail::blocking_adaptation::disallowed_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::blocking_adaptation::disallowed_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::blocking_adaptation::disallowed_t<0>::       query_static_constexpr_member<T>::value();@@ -911,7 +1019,7 @@  template <typename T> struct static_query<T, execution::blocking_adaptation_t::disallowed_t,-  enable_if_t<+  typename enable_if<     !execution::detail::blocking_adaptation::disallowed_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::blocking_adaptation::disallowed_t<0>::@@ -919,14 +1027,14 @@       && !traits::query_free<T,         execution::blocking_adaptation_t::disallowed_t>::is_valid       && !can_query<T, execution::blocking_adaptation_t::allowed_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef execution::blocking_adaptation_t::disallowed_t result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return result_type();   }@@ -934,18 +1042,18 @@  template <typename T> struct static_query<T, execution::blocking_adaptation_t::allowed_t,-  enable_if_t<+  typename enable_if<     execution::detail::blocking_adaptation::allowed_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::blocking_adaptation::allowed_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::blocking_adaptation::allowed_t<0>::       query_static_constexpr_member<T>::value();@@ -955,17 +1063,45 @@ #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::blocking_adaptation_t::disallowed_t,+  typename enable_if<+    static_query<T, execution::blocking_adaptation_t::disallowed_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::blocking_adaptation_t::disallowed_t>::result_type,+        execution::blocking_adaptation_t::disallowed_t>::value));+};++template <typename T>+struct static_require<T, execution::blocking_adaptation_t::allowed_t,+  typename enable_if<+    static_query<T, execution::blocking_adaptation_t::allowed_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::blocking_adaptation_t::allowed_t>::result_type,+        execution::blocking_adaptation_t::allowed_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)+ #if !defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)  template <typename T> struct require_free_default<T, execution::blocking_adaptation_t::allowed_t,-  enable_if_t<-    is_same<T, decay_t<T>>::value+  typename enable_if<+    is_same<T, typename decay<T>::type>::value       && execution::is_executor<T>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef execution::detail::blocking_adaptation::adapter<T> result_type; }; @@ -975,10 +1111,10 @@  template <typename Executor> struct equality_comparable<-  execution::detail::blocking_adaptation::adapter<Executor>>+  execution::detail::blocking_adaptation::adapter<Executor> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); };  #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -989,8 +1125,8 @@ struct execute_member<   execution::detail::blocking_adaptation::adapter<Executor>, Function> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; }; @@ -1001,13 +1137,13 @@ template <typename Executor, int I> struct query_static_constexpr_member<   execution::detail::blocking_adaptation::adapter<Executor>,-  execution::detail::blocking_adaptation_t<I>>+  execution::detail::blocking_adaptation_t<I> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef execution::blocking_adaptation_t::allowed_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -1016,13 +1152,13 @@ template <typename Executor, int I> struct query_static_constexpr_member<   execution::detail::blocking_adaptation::adapter<Executor>,-  execution::detail::blocking_adaptation::allowed_t<I>>+  execution::detail::blocking_adaptation::allowed_t<I> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef execution::blocking_adaptation_t::allowed_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -1031,13 +1167,13 @@ template <typename Executor, int I> struct query_static_constexpr_member<   execution::detail::blocking_adaptation::adapter<Executor>,-  execution::detail::blocking_adaptation::disallowed_t<I>>+  execution::detail::blocking_adaptation::disallowed_t<I> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef execution::blocking_adaptation_t::allowed_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -1050,14 +1186,14 @@ template <typename Executor, typename Property> struct query_member<   execution::detail::blocking_adaptation::adapter<Executor>, Property,-  enable_if_t<+  typename enable_if<     can_query<const Executor&, Property>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<Executor, Property>::value;-  typedef query_result_t<Executor, Property> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_query<Executor, Property>::value));+  typedef typename query_result<Executor, Property>::type result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -1067,25 +1203,26 @@ template <typename Executor, int I> struct require_member<   execution::detail::blocking_adaptation::adapter<Executor>,-  execution::detail::blocking_adaptation::disallowed_t<I>>+  execution::detail::blocking_adaptation::disallowed_t<I> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef Executor result_type; };  template <typename Executor, typename Property> struct require_member<   execution::detail::blocking_adaptation::adapter<Executor>, Property,-  enable_if_t<+  typename enable_if<     can_require<const Executor&, Property>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_require<Executor, Property>::value;-  typedef execution::detail::blocking_adaptation::adapter<-    decay_t<require_result_t<Executor, Property>>> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_require<Executor, Property>::value));+  typedef execution::detail::blocking_adaptation::adapter<typename decay<+    typename require_result<Executor, Property>::type+      >::type> result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -1095,15 +1232,16 @@ template <typename Executor, typename Property> struct prefer_member<   execution::detail::blocking_adaptation::adapter<Executor>, Property,-  enable_if_t<+  typename enable_if<     can_prefer<const Executor&, Property>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_prefer<Executor, Property>::value;-  typedef execution::detail::blocking_adaptation::adapter<-    decay_t<prefer_result_t<Executor, Property>>> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_prefer<Executor, Property>::value));+  typedef execution::detail::blocking_adaptation::adapter<typename decay<+    typename prefer_result<Executor, Property>::type+      >::type> result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
+ link/modules/asio-standalone/asio/include/asio/execution/bulk_execute.hpp view
@@ -0,0 +1,402 @@+//+// execution/bulk_execute.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_BULK_EXECUTE_HPP+#define ASIO_EXECUTION_BULK_EXECUTE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/bulk_guarantee.hpp"+#include "asio/execution/detail/bulk_sender.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/sender.hpp"+#include "asio/traits/bulk_execute_member.hpp"+#include "asio/traits/bulk_execute_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that creates a bulk sender.+/**+ * The name <tt>execution::bulk_execute</tt> denotes a customisation point+ * object. If <tt>is_convertible_v<N, size_t></tt> is true, then the expression+ * <tt>execution::bulk_execute(S, F, N)</tt> for some subexpressions+ * <tt>S</tt>, <tt>F</tt>, and <tt>N</tt> is expression-equivalent to:+ *+ * @li <tt>S.bulk_execute(F, N)</tt>, if that expression is valid. If the+ *   function selected does not execute <tt>N</tt> invocations of the function+ *   object <tt>F</tt> on the executor <tt>S</tt> in bulk with forward progress+ *   guarantee <tt>asio::query(S, execution::bulk_guarantee)</tt>, and+ *   the result of that function does not model <tt>sender<void></tt>, the+ *   program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>bulk_execute(S, F, N)</tt>, if that expression is valid,+ *   with overload resolution performed in a context that includes the+ *   declaration <tt>void bulk_execute();</tt> and that does not include a+ *   declaration of <tt>execution::bulk_execute</tt>. If the function selected+ *   by overload resolution does not execute <tt>N</tt> invocations of the+ *   function object <tt>F</tt> on the executor <tt>S</tt> in bulk with forward+ *   progress guarantee <tt>asio::query(E,+ *   execution::bulk_guarantee)</tt>, and the result of that function does not+ *   model <tt>sender<void></tt>, the program is ill-formed with no diagnostic+ *   required.+ *+ * @li Otherwise, if the types <tt>F</tt> and+ *   <tt>executor_index_t<remove_cvref_t<S>></tt> model <tt>invocable</tt> and+ *   if <tt>asio::query(S, execution::bulk_guarantee)</tt> equals+ *   <tt>execution::bulk_guarantee.unsequenced</tt>, then+ *+ *    - Evaluates <tt>DECAY_COPY(std::forward<decltype(F)>(F))</tt> on the+ *      calling thread to create a function object <tt>cf</tt>. [Note:+ *      Additional copies of <tt>cf</tt> may subsequently be created. --end+ *      note.]+ *+ *    - For each value of <tt>i</tt> in <tt>N</tt>, <tt>cf(i)</tt> (or copy of+ *      <tt>cf</tt>)) will be invoked at most once by an execution agent that is+ *      unique for each value of <tt>i</tt>.+ *+ *    - May block pending completion of one or more invocations of <tt>cf</tt>.+ *+ *    - Synchronizes with (C++Std [intro.multithread]) the invocations of+ *      <tt>cf</tt>.+ *+ * @li Otherwise, <tt>execution::bulk_execute(S, F, N)</tt> is ill-formed.+ */+inline constexpr unspecified bulk_execute = unspecified;++/// A type trait that determines whether a @c bulk_execute expression is+/// well-formed.+/**+ * Class template @c can_bulk_execute is a trait that is derived from @c+ * true_type if the expression <tt>execution::bulk_execute(std::declval<S>(),+ * std::declval<F>(), std::declval<N>)</tt> is well formed; otherwise @c+ * false_type.+ */+template <typename S, typename F, typename N>+struct can_bulk_execute :+  integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_bulk_execute_fn {++using asio::declval;+using asio::enable_if;+using asio::execution::bulk_guarantee_t;+using asio::execution::detail::bulk_sender;+using asio::execution::executor_index;+using asio::execution::is_sender;+using asio::is_convertible;+using asio::is_same;+using asio::remove_cvref;+using asio::result_of;+using asio::traits::bulk_execute_free;+using asio::traits::bulk_execute_member;+using asio::traits::static_require;++void bulk_execute();++enum overload_type+{+  call_member,+  call_free,+  adapter,+  ill_formed+};++template <typename S, typename Args, typename = void, typename = void,+    typename = void, typename = void, typename = void, typename = void>+struct call_traits+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++template <typename S, typename F, typename N>+struct call_traits<S, void(F, N),+  typename enable_if<+    is_convertible<N, std::size_t>::value+  >::type,+  typename enable_if<+    bulk_execute_member<S, F, N>::is_valid+  >::type,+  typename enable_if<+    is_sender<+      typename bulk_execute_member<S, F, N>::result_type+    >::value+  >::type> :+  bulk_execute_member<S, F, N>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename S, typename F, typename N>+struct call_traits<S, void(F, N),+  typename enable_if<+    is_convertible<N, std::size_t>::value+  >::type,+  typename enable_if<+    !bulk_execute_member<S, F, N>::is_valid+  >::type,+  typename enable_if<+    bulk_execute_free<S, F, N>::is_valid+  >::type,+  typename enable_if<+    is_sender<+      typename bulk_execute_free<S, F, N>::result_type+    >::value+  >::type> :+  bulk_execute_free<S, F, N>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename S, typename F, typename N>+struct call_traits<S, void(F, N),+  typename enable_if<+    is_convertible<N, std::size_t>::value+  >::type,+  typename enable_if<+    !bulk_execute_member<S, F, N>::is_valid+  >::type,+  typename enable_if<+    !bulk_execute_free<S, F, N>::is_valid+  >::type,+  typename enable_if<+    is_sender<S>::value+  >::type,+  typename enable_if<+    is_same<+      typename result_of<+        F(typename executor_index<typename remove_cvref<S>::type>::type)+      >::type,+      typename result_of<+        F(typename executor_index<typename remove_cvref<S>::type>::type)+      >::type+    >::value+  >::type,+  typename enable_if<+    static_require<S, bulk_guarantee_t::unsequenced_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef bulk_sender<S, F, N> result_type;+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+  template <typename S, typename F, typename N>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(F, N)>::overload == call_member,+    typename call_traits<S, void(F, N)>::result_type+  >::type+  operator()(S&& s, F&& f, N&& n) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(F, N)>::is_noexcept))+  {+    return ASIO_MOVE_CAST(S)(s).bulk_execute(+        ASIO_MOVE_CAST(F)(f), ASIO_MOVE_CAST(N)(n));+  }++  template <typename S, typename F, typename N>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(F, N)>::overload == call_free,+    typename call_traits<S, void(F, N)>::result_type+  >::type+  operator()(S&& s, F&& f, N&& n) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(F, N)>::is_noexcept))+  {+    return bulk_execute(ASIO_MOVE_CAST(S)(s),+        ASIO_MOVE_CAST(F)(f), ASIO_MOVE_CAST(N)(n));+  }++  template <typename S, typename F, typename N>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(F, N)>::overload == adapter,+    typename call_traits<S, void(F, N)>::result_type+  >::type+  operator()(S&& s, F&& f, N&& n) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(F, N)>::is_noexcept))+  {+    return typename call_traits<S, void(F, N)>::result_type(+        ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(F)(f),+        ASIO_MOVE_CAST(N)(n));+  }+#else // defined(ASIO_HAS_MOVE)+  template <typename S, typename F, typename N>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(const F&, const N&)>::overload == call_member,+    typename call_traits<S, void(const F&, const N&)>::result_type+  >::type+  operator()(S& s, const F& f, const N& n) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(const F&, const N&)>::is_noexcept))+  {+    return s.bulk_execute(ASIO_MOVE_CAST(F)(f),+        ASIO_MOVE_CAST(N)(n));+  }++  template <typename S, typename F, typename N>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(const F&, const N&)>::overload == call_member,+    typename call_traits<S, void(const F&, const N&)>::result_type+  >::type+  operator()(const S& s, const F& f, const N& n) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(const F&, const N&)>::is_noexcept))+  {+    return s.bulk_execute(ASIO_MOVE_CAST(F)(f),+        ASIO_MOVE_CAST(N)(n));+  }++  template <typename S, typename F, typename N>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(const F&, const N&)>::overload == call_free,+    typename call_traits<S, void(const F&, const N&)>::result_type+  >::type+  operator()(S& s, const F& f, const N& n) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(const F&, const N&)>::is_noexcept))+  {+    return bulk_execute(s, ASIO_MOVE_CAST(F)(f),+        ASIO_MOVE_CAST(N)(n));+  }++  template <typename S, typename F, typename N>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(const F&, const N&)>::overload == call_free,+    typename call_traits<S, void(const F&, const N&)>::result_type+  >::type+  operator()(const S& s, const F& f, const N& n) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(const F&, const N&)>::is_noexcept))+  {+    return bulk_execute(s, ASIO_MOVE_CAST(F)(f),+        ASIO_MOVE_CAST(N)(n));+  }++  template <typename S, typename F, typename N>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(const F&, const N&)>::overload == adapter,+    typename call_traits<S, void(const F&, const N&)>::result_type+  >::type+  operator()(S& s, const F& f, const N& n) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(const F&, const N&)>::is_noexcept))+  {+    return typename call_traits<S, void(const F&, const N&)>::result_type(+        s, ASIO_MOVE_CAST(F)(f), ASIO_MOVE_CAST(N)(n));+  }++  template <typename S, typename F, typename N>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(const F&, const N&)>::overload == adapter,+    typename call_traits<S, void(const F&, const N&)>::result_type+  >::type+  operator()(const S& s, const F& f, const N& n) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(const F&, const N&)>::is_noexcept))+  {+    return typename call_traits<S, void(const F&, const N&)>::result_type(+        s, ASIO_MOVE_CAST(F)(f), ASIO_MOVE_CAST(N)(n));+  }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+  static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_bulk_execute_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR+  const asio_execution_bulk_execute_fn::impl& bulk_execute =+    asio_execution_bulk_execute_fn::static_instance<>::instance;++} // namespace++template <typename S, typename F, typename N>+struct can_bulk_execute :+  integral_constant<bool,+    asio_execution_bulk_execute_fn::call_traits<+      S, void(F, N)>::overload !=+        asio_execution_bulk_execute_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename F, typename N>+constexpr bool can_bulk_execute_v = can_bulk_execute<S, F, N>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename F, typename N>+struct is_nothrow_bulk_execute :+  integral_constant<bool,+    asio_execution_bulk_execute_fn::call_traits<+      S, void(F, N)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename F, typename N>+constexpr bool is_nothrow_bulk_execute_v+  = is_nothrow_bulk_execute<S, F, N>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename F, typename N>+struct bulk_execute_result+{+  typedef typename asio_execution_bulk_execute_fn::call_traits<+      S, void(F, N)>::result_type type;+};++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_BULK_EXECUTE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/bulk_guarantee.hpp view
@@ -0,0 +1,1252 @@+//+// execution/bulk_guarantee.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_BULK_GUARANTEE_HPP+#define ASIO_EXECUTION_BULK_GUARANTEE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp"+#include "asio/is_applicable_property.hpp"+#include "asio/query.hpp"+#include "asio/traits/query_free.hpp"+#include "asio/traits/query_member.hpp"+#include "asio/traits/query_static_constexpr_member.hpp"+#include "asio/traits/static_query.hpp"+#include "asio/traits/static_require.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++#if defined(GENERATING_DOCUMENTATION)++namespace execution {++/// A property to communicate the forward progress and ordering guarantees of+/// execution agents associated with the bulk execution.+struct bulk_guarantee_t+{+  /// The bulk_guarantee_t property applies to executors, senders, and+  /// schedulers.+  template <typename T>+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;++  /// The top-level bulk_guarantee_t property cannot be required.+  static constexpr bool is_requirable = false;++  /// The top-level bulk_guarantee_t property cannot be preferred.+  static constexpr bool is_preferable = false;++  /// The type returned by queries against an @c any_executor.+  typedef bulk_guarantee_t polymorphic_query_result_type;++  /// A sub-property that indicates that execution agents within the same bulk+  /// execution may be parallelised and vectorised.+  struct unsequenced_t+  {+    /// The bulk_guarantee_t::unsequenced_t property applies to executors,+    /// senders, and schedulers.+    template <typename T>+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;++    /// The bulk_guarantee_t::unsequenced_t property can be required.+    static constexpr bool is_requirable = true;++    /// The bulk_guarantee_t::unsequenced_t property can be preferred.+    static constexpr bool is_preferable = true;++    /// The type returned by queries against an @c any_executor.+    typedef bulk_guarantee_t polymorphic_query_result_type;++    /// Default constructor.+    constexpr unsequenced_t();++    /// Get the value associated with a property object.+    /**+     * @returns unsequenced_t();+     */+    static constexpr bulk_guarantee_t value();+  };++  /// A sub-property that indicates that execution agents within the same bulk+  /// execution may not be parallelised and vectorised.+  struct sequenced_t+  {+    /// The bulk_guarantee_t::sequenced_t property applies to executors,+    /// senders, and schedulers.+    template <typename T>+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;++    /// The bulk_guarantee_t::sequenced_t property can be required.+    static constexpr bool is_requirable = true;++    /// The bulk_guarantee_t::sequenced_t property can be preferred.+    static constexpr bool is_preferable = true;++    /// The type returned by queries against an @c any_executor.+    typedef bulk_guarantee_t polymorphic_query_result_type;++    /// Default constructor.+    constexpr sequenced_t();++    /// Get the value associated with a property object.+    /**+     * @returns sequenced_t();+     */+    static constexpr bulk_guarantee_t value();+  };++  /// A sub-property that indicates that execution agents within the same bulk+  /// execution may be parallelised.+  struct parallel_t+  {+    /// The bulk_guarantee_t::parallel_t property applies to executors,+    /// senders, and schedulers.+    template <typename T>+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;++    /// The bulk_guarantee_t::parallel_t property can be required.+    static constexpr bool is_requirable = true;++    /// The bulk_guarantee_t::parallel_t property can be preferred.+    static constexpr bool is_preferable = true;++    /// The type returned by queries against an @c any_executor.+    typedef bulk_guarantee_t polymorphic_query_result_type;++    /// Default constructor.+    constexpr parallel_t();++    /// Get the value associated with a property object.+    /**+     * @returns parallel_t();+     */+    static constexpr bulk_guarantee_t value();+  };++  /// A special value used for accessing the bulk_guarantee_t::unsequenced_t+  /// property.+  static constexpr unsequenced_t unsequenced;++  /// A special value used for accessing the bulk_guarantee_t::sequenced_t+  /// property.+  static constexpr sequenced_t sequenced;++  /// A special value used for accessing the bulk_guarantee_t::parallel_t+  /// property.+  static constexpr parallel_t parallel;++  /// Default constructor.+  constexpr bulk_guarantee_t();++  /// Construct from a sub-property value.+  constexpr bulk_guarantee_t(unsequenced_t);++  /// Construct from a sub-property value.+  constexpr bulk_guarantee_t(sequenced_t);++  /// Construct from a sub-property value.+  constexpr bulk_guarantee_t(parallel_t);++  /// Compare property values for equality.+  friend constexpr bool operator==(+      const bulk_guarantee_t& a, const bulk_guarantee_t& b) noexcept;++  /// Compare property values for inequality.+  friend constexpr bool operator!=(+      const bulk_guarantee_t& a, const bulk_guarantee_t& b) noexcept;+};++/// A special value used for accessing the bulk_guarantee_t property.+constexpr bulk_guarantee_t bulk_guarantee;++} // namespace execution++#else // defined(GENERATING_DOCUMENTATION)++namespace execution {+namespace detail {+namespace bulk_guarantee {++template <int I> struct unsequenced_t;+template <int I> struct sequenced_t;+template <int I> struct parallel_t;++} // namespace bulk_guarantee++template <int I = 0>+struct bulk_guarantee_t+{+#if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED)+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);+  typedef bulk_guarantee_t polymorphic_query_result_type;++  typedef detail::bulk_guarantee::unsequenced_t<I> unsequenced_t;+  typedef detail::bulk_guarantee::sequenced_t<I> sequenced_t;+  typedef detail::bulk_guarantee::parallel_t<I> parallel_t;++  ASIO_CONSTEXPR bulk_guarantee_t()+    : value_(-1)+  {+  }++  ASIO_CONSTEXPR bulk_guarantee_t(unsequenced_t)+    : value_(0)+  {+  }++  ASIO_CONSTEXPR bulk_guarantee_t(sequenced_t)+    : value_(1)+  {+  }++  ASIO_CONSTEXPR bulk_guarantee_t(parallel_t)+    : value_(2)+  {+  }++  template <typename T>+  struct proxy+  {+#if defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)+    struct type+    {+      template <typename P>+      auto query(ASIO_MOVE_ARG(P) p) const+        noexcept(+          noexcept(+            declval<typename conditional<true, T, P>::type>().query(+              ASIO_MOVE_CAST(P)(p))+          )+        )+        -> decltype(+          declval<typename conditional<true, T, P>::type>().query(+            ASIO_MOVE_CAST(P)(p))+        );+    };+#else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)+    typedef T type;+#endif // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)+  };++  template <typename T>+  struct static_proxy+  {+#if defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)+    struct type+    {+      template <typename P>+      static constexpr auto query(ASIO_MOVE_ARG(P) p)+        noexcept(+          noexcept(+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+          )+        )+        -> decltype(+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))+        )+      {+        return T::query(ASIO_MOVE_CAST(P)(p));+      }+    };+#else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)+    typedef T type;+#endif // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)+  };++  template <typename T>+  struct query_member :+    traits::query_member<typename proxy<T>::type, bulk_guarantee_t> {};++  template <typename T>+  struct query_static_constexpr_member :+    traits::query_static_constexpr_member<+      typename static_proxy<T>::type, bulk_guarantee_t> {};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+  template <typename T>+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type+  static_query()+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))+  {+    return query_static_constexpr_member<T>::value();+  }++  template <typename T>+  static ASIO_CONSTEXPR+  typename traits::static_query<T, unsequenced_t>::result_type+  static_query(+      typename enable_if<+        !query_static_constexpr_member<T>::is_valid+      >::type* = 0,+      typename enable_if<+        !query_member<T>::is_valid+      >::type* = 0,+      typename enable_if<+        traits::static_query<T, unsequenced_t>::is_valid+      >::type* = 0) ASIO_NOEXCEPT+  {+    return traits::static_query<T, unsequenced_t>::value();+  }++  template <typename T>+  static ASIO_CONSTEXPR+  typename traits::static_query<T, sequenced_t>::result_type+  static_query(+      typename enable_if<+        !query_static_constexpr_member<T>::is_valid+      >::type* = 0,+      typename enable_if<+        !query_member<T>::is_valid+      >::type* = 0,+      typename enable_if<+        !traits::static_query<T, unsequenced_t>::is_valid+      >::type* = 0,+      typename enable_if<+        traits::static_query<T, sequenced_t>::is_valid+      >::type* = 0) ASIO_NOEXCEPT+  {+    return traits::static_query<T, sequenced_t>::value();+  }++  template <typename T>+  static ASIO_CONSTEXPR+  typename traits::static_query<T, parallel_t>::result_type+  static_query(+      typename enable_if<+        !query_static_constexpr_member<T>::is_valid+      >::type* = 0,+      typename enable_if<+        !query_member<T>::is_valid+      >::type* = 0,+      typename enable_if<+        !traits::static_query<T, unsequenced_t>::is_valid+      >::type* = 0,+      typename enable_if<+        !traits::static_query<T, sequenced_t>::is_valid+      >::type* = 0,+      typename enable_if<+        traits::static_query<T, parallel_t>::is_valid+      >::type* = 0) ASIO_NOEXCEPT+  {+    return traits::static_query<T, parallel_t>::value();+  }++  template <typename E,+      typename T = decltype(bulk_guarantee_t::static_query<E>())>+  static ASIO_CONSTEXPR const T static_query_v+    = bulk_guarantee_t::static_query<E>();+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+       //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++  friend ASIO_CONSTEXPR bool operator==(+      const bulk_guarantee_t& a, const bulk_guarantee_t& b)+  {+    return a.value_ == b.value_;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const bulk_guarantee_t& a, const bulk_guarantee_t& b)+  {+    return a.value_ != b.value_;+  }++  struct convertible_from_bulk_guarantee_t+  {+    ASIO_CONSTEXPR convertible_from_bulk_guarantee_t(bulk_guarantee_t) {}+  };++  template <typename Executor>+  friend ASIO_CONSTEXPR bulk_guarantee_t query(+      const Executor& ex, convertible_from_bulk_guarantee_t,+      typename enable_if<+        can_query<const Executor&, unsequenced_t>::value+      >::type* = 0)+#if !defined(__clang__) // Clang crashes if noexcept is used here.+#if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&,+        bulk_guarantee_t<>::unsequenced_t>::value))+#else // defined(ASIO_MSVC)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, unsequenced_t>::value))+#endif // defined(ASIO_MSVC)+#endif // !defined(__clang__)+  {+    return asio::query(ex, unsequenced_t());+  }++  template <typename Executor>+  friend ASIO_CONSTEXPR bulk_guarantee_t query(+      const Executor& ex, convertible_from_bulk_guarantee_t,+      typename enable_if<+        !can_query<const Executor&, unsequenced_t>::value+      >::type* = 0,+      typename enable_if<+        can_query<const Executor&, sequenced_t>::value+      >::type* = 0)+#if !defined(__clang__) // Clang crashes if noexcept is used here.+#if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&,+        bulk_guarantee_t<>::sequenced_t>::value))+#else // defined(ASIO_MSVC)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, sequenced_t>::value))+#endif // defined(ASIO_MSVC)+#endif // !defined(__clang__)+  {+    return asio::query(ex, sequenced_t());+  }++  template <typename Executor>+  friend ASIO_CONSTEXPR bulk_guarantee_t query(+      const Executor& ex, convertible_from_bulk_guarantee_t,+      typename enable_if<+        !can_query<const Executor&, unsequenced_t>::value+      >::type* = 0,+      typename enable_if<+        !can_query<const Executor&, sequenced_t>::value+      >::type* = 0,+      typename enable_if<+        can_query<const Executor&, parallel_t>::value+      >::type* = 0)+#if !defined(__clang__) // Clang crashes if noexcept is used here.+#if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, bulk_guarantee_t<>::parallel_t>::value))+#else // defined(ASIO_MSVC)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, parallel_t>::value))+#endif // defined(ASIO_MSVC)+#endif // !defined(__clang__)+  {+    return asio::query(ex, parallel_t());+  }++  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(unsequenced_t, unsequenced);+  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(sequenced_t, sequenced);+  ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(parallel_t, parallel);++#if !defined(ASIO_HAS_CONSTEXPR)+  static const bulk_guarantee_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)++private:+  int value_;+};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+template <int I> template <typename E, typename T>+const T bulk_guarantee_t<I>::static_query_v;+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+       //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_CONSTEXPR)+template <int I>+const bulk_guarantee_t<I> bulk_guarantee_t<I>::instance;+#endif++template <int I>+const typename bulk_guarantee_t<I>::unsequenced_t+bulk_guarantee_t<I>::unsequenced;++template <int I>+const typename bulk_guarantee_t<I>::sequenced_t+bulk_guarantee_t<I>::sequenced;++template <int I>+const typename bulk_guarantee_t<I>::parallel_t+bulk_guarantee_t<I>::parallel;++namespace bulk_guarantee {++template <int I = 0>+struct unsequenced_t+{+#if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED)+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+  typedef bulk_guarantee_t<I> polymorphic_query_result_type;++  ASIO_CONSTEXPR unsequenced_t()+  {+  }++  template <typename T>+  struct query_member :+    traits::query_member<+      typename bulk_guarantee_t<I>::template proxy<T>::type,+        unsequenced_t> {};++  template <typename T>+  struct query_static_constexpr_member :+    traits::query_static_constexpr_member<+      typename bulk_guarantee_t<I>::template static_proxy<T>::type,+        unsequenced_t> {};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+  template <typename T>+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type+  static_query()+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))+  {+    return query_static_constexpr_member<T>::value();+  }++  template <typename T>+  static ASIO_CONSTEXPR unsequenced_t static_query(+      typename enable_if<+        !query_static_constexpr_member<T>::is_valid+      >::type* = 0,+      typename enable_if<+        !query_member<T>::is_valid+      >::type* = 0,+      typename enable_if<+        !traits::query_free<T, unsequenced_t>::is_valid+      >::type* = 0,+      typename enable_if<+        !can_query<T, sequenced_t<I> >::value+      >::type* = 0,+      typename enable_if<+        !can_query<T, parallel_t<I> >::value+      >::type* = 0) ASIO_NOEXCEPT+  {+    return unsequenced_t();+  }++  template <typename E, typename T = decltype(unsequenced_t::static_query<E>())>+  static ASIO_CONSTEXPR const T static_query_v+    = unsequenced_t::static_query<E>();+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+       //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++  static ASIO_CONSTEXPR bulk_guarantee_t<I> value()+  {+    return unsequenced_t();+  }++  friend ASIO_CONSTEXPR bool operator==(+      const unsequenced_t&, const unsequenced_t&)+  {+    return true;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const unsequenced_t&, const unsequenced_t&)+  {+    return false;+  }++  friend ASIO_CONSTEXPR bool operator==(+      const unsequenced_t&, const sequenced_t<I>&)+  {+    return false;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const unsequenced_t&, const sequenced_t<I>&)+  {+    return true;+  }++  friend ASIO_CONSTEXPR bool operator==(+      const unsequenced_t&, const parallel_t<I>&)+  {+    return false;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const unsequenced_t&, const parallel_t<I>&)+  {+    return true;+  }+};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+template <int I> template <typename E, typename T>+const T unsequenced_t<I>::static_query_v;+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+       //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++template <int I = 0>+struct sequenced_t+{+#if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED)+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+  typedef bulk_guarantee_t<I> polymorphic_query_result_type;++  ASIO_CONSTEXPR sequenced_t()+  {+  }++  template <typename T>+  struct query_member :+    traits::query_member<+      typename bulk_guarantee_t<I>::template proxy<T>::type,+        sequenced_t> {};++  template <typename T>+  struct query_static_constexpr_member :+    traits::query_static_constexpr_member<+      typename bulk_guarantee_t<I>::template static_proxy<T>::type,+        sequenced_t> {};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+  template <typename T>+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type+  static_query()+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))+  {+    return query_static_constexpr_member<T>::value();+  }++  template <typename E, typename T = decltype(sequenced_t::static_query<E>())>+  static ASIO_CONSTEXPR const T static_query_v+    = sequenced_t::static_query<E>();+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+       //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++  static ASIO_CONSTEXPR bulk_guarantee_t<I> value()+  {+    return sequenced_t();+  }++  friend ASIO_CONSTEXPR bool operator==(+      const sequenced_t&, const sequenced_t&)+  {+    return true;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const sequenced_t&, const sequenced_t&)+  {+    return false;+  }++  friend ASIO_CONSTEXPR bool operator==(+      const sequenced_t&, const unsequenced_t<I>&)+  {+    return false;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const sequenced_t&, const unsequenced_t<I>&)+  {+    return true;+  }++  friend ASIO_CONSTEXPR bool operator==(+      const sequenced_t&, const parallel_t<I>&)+  {+    return false;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const sequenced_t&, const parallel_t<I>&)+  {+    return true;+  }+};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+template <int I> template <typename E, typename T>+const T sequenced_t<I>::static_query_v;+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+       //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++template <int I>+struct parallel_t+{+#if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED)+#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);+  typedef bulk_guarantee_t<I> polymorphic_query_result_type;++  ASIO_CONSTEXPR parallel_t()+  {+  }++  template <typename T>+  struct query_member :+    traits::query_member<+      typename bulk_guarantee_t<I>::template proxy<T>::type,+        parallel_t> {};++  template <typename T>+  struct query_static_constexpr_member :+    traits::query_static_constexpr_member<+      typename bulk_guarantee_t<I>::template static_proxy<T>::type,+        parallel_t> {};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+  template <typename T>+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type+  static_query()+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))+  {+    return query_static_constexpr_member<T>::value();+  }++  template <typename E, typename T = decltype(parallel_t::static_query<E>())>+  static ASIO_CONSTEXPR const T static_query_v+    = parallel_t::static_query<E>();+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+       //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++  static ASIO_CONSTEXPR bulk_guarantee_t<I> value()+  {+    return parallel_t();+  }++  friend ASIO_CONSTEXPR bool operator==(+      const parallel_t&, const parallel_t&)+  {+    return true;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const parallel_t&, const parallel_t&)+  {+    return false;+  }++  friend ASIO_CONSTEXPR bool operator==(+      const parallel_t&, const unsequenced_t<I>&)+  {+    return false;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const parallel_t&, const unsequenced_t<I>&)+  {+    return true;+  }++  friend ASIO_CONSTEXPR bool operator==(+      const parallel_t&, const sequenced_t<I>&)+  {+    return false;+  }++  friend ASIO_CONSTEXPR bool operator!=(+      const parallel_t&, const sequenced_t<I>&)+  {+    return true;+  }+};++#if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+  && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)+template <int I> template <typename E, typename T>+const T parallel_t<I>::static_query_v;+#endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+       //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++} // namespace bulk_guarantee+} // namespace detail++typedef detail::bulk_guarantee_t<> bulk_guarantee_t;++#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr bulk_guarantee_t bulk_guarantee;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const bulk_guarantee_t&+  bulk_guarantee = bulk_guarantee_t::instance; }+#endif++} // namespace execution++#if !defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+struct is_applicable_property<T, execution::bulk_guarantee_t>+  : integral_constant<bool,+      execution::is_executor<T>::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value>+{+};++template <typename T>+struct is_applicable_property<T, execution::bulk_guarantee_t::unsequenced_t>+  : integral_constant<bool,+      execution::is_executor<T>::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value>+{+};++template <typename T>+struct is_applicable_property<T, execution::bulk_guarantee_t::sequenced_t>+  : integral_constant<bool,+      execution::is_executor<T>::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value>+{+};++template <typename T>+struct is_applicable_property<T, execution::bulk_guarantee_t::parallel_t>+  : integral_constant<bool,+      execution::is_executor<T>::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value>+{+};++#endif // !defined(ASIO_HAS_VARIABLE_TEMPLATES)++namespace traits {++#if !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)++template <typename T>+struct query_free_default<T, execution::bulk_guarantee_t,+  typename enable_if<+    can_query<T, execution::bulk_guarantee_t::unsequenced_t>::value+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::bulk_guarantee_t::unsequenced_t>::value));++  typedef execution::bulk_guarantee_t result_type;+};++template <typename T>+struct query_free_default<T, execution::bulk_guarantee_t,+  typename enable_if<+    !can_query<T, execution::bulk_guarantee_t::unsequenced_t>::value+      && can_query<T, execution::bulk_guarantee_t::sequenced_t>::value+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::bulk_guarantee_t::sequenced_t>::value));++  typedef execution::bulk_guarantee_t result_type;+};++template <typename T>+struct query_free_default<T, execution::bulk_guarantee_t,+  typename enable_if<+    !can_query<T, execution::bulk_guarantee_t::unsequenced_t>::value+      && !can_query<T, execution::bulk_guarantee_t::sequenced_t>::value+      && can_query<T, execution::bulk_guarantee_t::parallel_t>::value+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::bulk_guarantee_t::parallel_t>::value));++  typedef execution::bulk_guarantee_t result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \+  || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++template <typename T>+struct static_query<T, execution::bulk_guarantee_t,+  typename enable_if<+    execution::detail::bulk_guarantee_t<0>::+      query_static_constexpr_member<T>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++  typedef typename execution::detail::bulk_guarantee_t<0>::+    query_static_constexpr_member<T>::result_type result_type;++  static ASIO_CONSTEXPR result_type value()+  {+    return execution::detail::bulk_guarantee_t<0>::+      query_static_constexpr_member<T>::value();+  }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t,+  typename enable_if<+    !execution::detail::bulk_guarantee_t<0>::+        query_static_constexpr_member<T>::is_valid+      && !execution::detail::bulk_guarantee_t<0>::+        query_member<T>::is_valid+      && traits::static_query<T,+        execution::bulk_guarantee_t::unsequenced_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++  typedef typename traits::static_query<T,+    execution::bulk_guarantee_t::unsequenced_t>::result_type result_type;++  static ASIO_CONSTEXPR result_type value()+  {+    return traits::static_query<T,+        execution::bulk_guarantee_t::unsequenced_t>::value();+  }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t,+  typename enable_if<+    !execution::detail::bulk_guarantee_t<0>::+        query_static_constexpr_member<T>::is_valid+      && !execution::detail::bulk_guarantee_t<0>::+        query_member<T>::is_valid+      && !traits::static_query<T,+        execution::bulk_guarantee_t::unsequenced_t>::is_valid+      && traits::static_query<T,+        execution::bulk_guarantee_t::sequenced_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++  typedef typename traits::static_query<T,+    execution::bulk_guarantee_t::sequenced_t>::result_type result_type;++  static ASIO_CONSTEXPR result_type value()+  {+    return traits::static_query<T,+        execution::bulk_guarantee_t::sequenced_t>::value();+  }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t,+  typename enable_if<+    !execution::detail::bulk_guarantee_t<0>::+        query_static_constexpr_member<T>::is_valid+      && !execution::detail::bulk_guarantee_t<0>::+        query_member<T>::is_valid+      && !traits::static_query<T,+        execution::bulk_guarantee_t::unsequenced_t>::is_valid+      && !traits::static_query<T,+        execution::bulk_guarantee_t::sequenced_t>::is_valid+      && traits::static_query<T,+        execution::bulk_guarantee_t::parallel_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++  typedef typename traits::static_query<T,+    execution::bulk_guarantee_t::parallel_t>::result_type result_type;++  static ASIO_CONSTEXPR result_type value()+  {+    return traits::static_query<T,+        execution::bulk_guarantee_t::parallel_t>::value();+  }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t::unsequenced_t,+  typename enable_if<+    execution::detail::bulk_guarantee::unsequenced_t<0>::+      query_static_constexpr_member<T>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++  typedef typename execution::detail::bulk_guarantee::unsequenced_t<0>::+    query_static_constexpr_member<T>::result_type result_type;++  static ASIO_CONSTEXPR result_type value()+  {+    return execution::detail::bulk_guarantee::unsequenced_t<0>::+      query_static_constexpr_member<T>::value();+  }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t::unsequenced_t,+  typename enable_if<+    !execution::detail::bulk_guarantee::unsequenced_t<0>::+        query_static_constexpr_member<T>::is_valid+      && !execution::detail::bulk_guarantee::unsequenced_t<0>::+        query_member<T>::is_valid+      && !traits::query_free<T,+        execution::bulk_guarantee_t::unsequenced_t>::is_valid+      && !can_query<T, execution::bulk_guarantee_t::sequenced_t>::value+      && !can_query<T, execution::bulk_guarantee_t::parallel_t>::value+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++  typedef execution::bulk_guarantee_t::unsequenced_t result_type;++  static ASIO_CONSTEXPR result_type value()+  {+    return result_type();+  }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t::sequenced_t,+  typename enable_if<+    execution::detail::bulk_guarantee::sequenced_t<0>::+      query_static_constexpr_member<T>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++  typedef typename execution::detail::bulk_guarantee::sequenced_t<0>::+    query_static_constexpr_member<T>::result_type result_type;++  static ASIO_CONSTEXPR result_type value()+  {+    return execution::detail::bulk_guarantee::sequenced_t<0>::+      query_static_constexpr_member<T>::value();+  }+};++template <typename T>+struct static_query<T, execution::bulk_guarantee_t::parallel_t,+  typename enable_if<+    execution::detail::bulk_guarantee::parallel_t<0>::+      query_static_constexpr_member<T>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++  typedef typename execution::detail::bulk_guarantee::parallel_t<0>::+    query_static_constexpr_member<T>::result_type result_type;++  static ASIO_CONSTEXPR result_type value()+  {+    return execution::detail::bulk_guarantee::parallel_t<0>::+      query_static_constexpr_member<T>::value();+  }+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)+       //   || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::bulk_guarantee_t::unsequenced_t,+  typename enable_if<+    static_query<T, execution::bulk_guarantee_t::unsequenced_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::bulk_guarantee_t::unsequenced_t>::result_type,+        execution::bulk_guarantee_t::unsequenced_t>::value));+};++template <typename T>+struct static_require<T, execution::bulk_guarantee_t::sequenced_t,+  typename enable_if<+    static_query<T, execution::bulk_guarantee_t::sequenced_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::bulk_guarantee_t::sequenced_t>::result_type,+        execution::bulk_guarantee_t::sequenced_t>::value));+};++template <typename T>+struct static_require<T, execution::bulk_guarantee_t::parallel_t,+  typename enable_if<+    static_query<T, execution::bulk_guarantee_t::parallel_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::bulk_guarantee_t::parallel_t>::result_type,+        execution::bulk_guarantee_t::parallel_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++} // namespace traits++#endif // defined(GENERATING_DOCUMENTATION)++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_BULK_GUARANTEE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/connect.hpp view
@@ -0,0 +1,494 @@+//+// execution/connect.hpp+// ~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_CONNECT_HPP+#define ASIO_EXECUTION_CONNECT_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/as_invocable.hpp"+#include "asio/execution/detail/as_operation.hpp"+#include "asio/execution/detail/as_receiver.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/operation_state.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/sender.hpp"+#include "asio/traits/connect_member.hpp"+#include "asio/traits/connect_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that connects a sender to a receiver.+/**+ * The name <tt>execution::connect</tt> denotes a customisation point object.+ * For some subexpressions <tt>s</tt> and <tt>r</tt>, let <tt>S</tt> be a type+ * such that <tt>decltype((s))</tt> is <tt>S</tt> and let <tt>R</tt> be a type+ * such that <tt>decltype((r))</tt> is <tt>R</tt>. The expression+ * <tt>execution::connect(s, r)</tt> is expression-equivalent to:+ *+ * @li <tt>s.connect(r)</tt>, if that expression is valid, if its type+ *   satisfies <tt>operation_state</tt>, and if <tt>S</tt> satisfies+ *   <tt>sender</tt>.+ *+ * @li Otherwise, <tt>connect(s, r)</tt>, if that expression is valid, if its+ *   type satisfies <tt>operation_state</tt>, and if <tt>S</tt> satisfies+ *   <tt>sender</tt>, with overload resolution performed in a context that+ *   includes the declaration <tt>void connect();</tt> and that does not include+ *   a declaration of <tt>execution::connect</tt>.+ *+ * @li Otherwise, <tt>as_operation{s, r}</tt>, if <tt>r</tt> is not an instance+ *  of <tt>as_receiver<F, S></tt> for some type <tt>F</tt>, and if+ *  <tt>receiver_of<R> && executor_of<remove_cvref_t<S>,+ *  as_invocable<remove_cvref_t<R>, S>></tt> is <tt>true</tt>, where+ *  <tt>as_operation</tt> is an implementation-defined class equivalent to+ *  @code template <class S, class R>+ *  struct as_operation+ *  {+ *    remove_cvref_t<S> e_;+ *    remove_cvref_t<R> r_;+ *    void start() noexcept try {+ *      execution::execute(std::move(e_),+ *          as_invocable<remove_cvref_t<R>, S>{r_});+ *    } catch(...) {+ *      execution::set_error(std::move(r_), current_exception());+ *    }+ *  }; @endcode+ *  and <tt>as_invocable</tt> is a class template equivalent to the following:+ *  @code template<class R>+ *  struct as_invocable+ *  {+ *    R* r_;+ *    explicit as_invocable(R& r) noexcept+ *      : r_(std::addressof(r)) {}+ *    as_invocable(as_invocable && other) noexcept+ *      : r_(std::exchange(other.r_, nullptr)) {}+ *    ~as_invocable() {+ *      if(r_)+ *        execution::set_done(std::move(*r_));+ *    }+ *    void operator()() & noexcept try {+ *      execution::set_value(std::move(*r_));+ *      r_ = nullptr;+ *    } catch(...) {+ *      execution::set_error(std::move(*r_), current_exception());+ *      r_ = nullptr;+ *    }+ *  };+ *  @endcode+ *+ * @li Otherwise, <tt>execution::connect(s, r)</tt> is ill-formed.+ */+inline constexpr unspecified connect = unspecified;++/// A type trait that determines whether a @c connect expression is+/// well-formed.+/**+ * Class template @c can_connect is a trait that is derived from+ * @c true_type if the expression <tt>execution::connect(std::declval<S>(),+ * std::declval<R>())</tt> is well formed; otherwise @c false_type.+ */+template <typename S, typename R>+struct can_connect :+  integral_constant<bool, automatically_determined>+{+};++/// A type trait to determine the result of a @c connect expression.+template <typename S, typename R>+struct connect_result+{+  /// The type of the connect expression.+  /**+   * The type of the expression <tt>execution::connect(std::declval<S>(),+   * std::declval<R>())</tt>.+   */+  typedef automatically_determined type;+};++/// A type alis to determine the result of a @c connect expression.+template <typename S, typename R>+using connect_result_t = typename connect_result<S, R>::type;++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_connect_fn {++using asio::conditional;+using asio::declval;+using asio::enable_if;+using asio::execution::detail::as_invocable;+using asio::execution::detail::as_operation;+using asio::execution::detail::is_as_receiver;+using asio::execution::is_executor_of;+using asio::execution::is_operation_state;+using asio::execution::is_receiver;+using asio::execution::is_sender;+using asio::false_type;+using asio::remove_cvref;+using asio::traits::connect_free;+using asio::traits::connect_member;++void connect();++enum overload_type+{+  call_member,+  call_free,+  adapter,+  ill_formed+};++template <typename S, typename R, typename = void,+   typename = void, typename = void, typename = void>+struct call_traits+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++template <typename S, typename R>+struct call_traits<S, void(R),+  typename enable_if<+    connect_member<S, R>::is_valid+  >::type,+  typename enable_if<+    is_operation_state<typename connect_member<S, R>::result_type>::value+  >::type,+  typename enable_if<+    is_sender<typename remove_cvref<S>::type>::value+  >::type> :+  connect_member<S, R>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename S, typename R>+struct call_traits<S, void(R),+  typename enable_if<+    !connect_member<S, R>::is_valid+  >::type,+  typename enable_if<+    connect_free<S, R>::is_valid+  >::type,+  typename enable_if<+    is_operation_state<typename connect_free<S, R>::result_type>::value+  >::type,+  typename enable_if<+    is_sender<typename remove_cvref<S>::type>::value+  >::type> :+  connect_free<S, R>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename S, typename R>+struct call_traits<S, void(R),+  typename enable_if<+    !connect_member<S, R>::is_valid+  >::type,+  typename enable_if<+    !connect_free<S, R>::is_valid+  >::type,+  typename enable_if<+    is_receiver<R>::value+  >::type,+  typename enable_if<+    conditional<+      !is_as_receiver<+        typename remove_cvref<R>::type+      >::value,+      is_executor_of<+        typename remove_cvref<S>::type,+        as_invocable<typename remove_cvref<R>::type, S>+      >,+      false_type+    >::type::value+  >::type>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef as_operation<S, R> result_type;+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(R)>::overload == call_member,+    typename call_traits<S, void(R)>::result_type+  >::type+  operator()(S&& s, R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(R)>::is_noexcept))+  {+    return ASIO_MOVE_CAST(S)(s).connect(ASIO_MOVE_CAST(R)(r));+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(R)>::overload == call_free,+    typename call_traits<S, void(R)>::result_type+  >::type+  operator()(S&& s, R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(R)>::is_noexcept))+  {+    return connect(ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(R)>::overload == adapter,+    typename call_traits<S, void(R)>::result_type+  >::type+  operator()(S&& s, R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(R)>::is_noexcept))+  {+    return typename call_traits<S, void(R)>::result_type(+        ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));+  }+#else // defined(ASIO_HAS_MOVE)+  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(R&)>::overload == call_member,+    typename call_traits<S&, void(R&)>::result_type+  >::type+  operator()(S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(R&)>::is_noexcept))+  {+    return s.connect(r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(R&)>::overload == call_member,+    typename call_traits<const S&, void(R&)>::result_type+  >::type+  operator()(const S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(R&)>::is_noexcept))+  {+    return s.connect(r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(R&)>::overload == call_free,+    typename call_traits<S&, void(R&)>::result_type+  >::type+  operator()(S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(R&)>::is_noexcept))+  {+    return connect(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(R&)>::overload == call_free,+    typename call_traits<const S&, void(R&)>::result_type+  >::type+  operator()(const S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(R&)>::is_noexcept))+  {+    return connect(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(R&)>::overload == adapter,+    typename call_traits<S&, void(R&)>::result_type+  >::type+  operator()(S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(R&)>::is_noexcept))+  {+    return typename call_traits<S&, void(R&)>::result_type(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(R&)>::overload == adapter,+    typename call_traits<const S&, void(R&)>::result_type+  >::type+  operator()(const S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(R&)>::is_noexcept))+  {+    return typename call_traits<const S&, void(R&)>::result_type(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(const R&)>::overload == call_member,+    typename call_traits<S&, void(const R&)>::result_type+  >::type+  operator()(S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(const R&)>::is_noexcept))+  {+    return s.connect(r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(const R&)>::overload == call_member,+    typename call_traits<const S&, void(const R&)>::result_type+  >::type+  operator()(const S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(const R&)>::is_noexcept))+  {+    return s.connect(r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(const R&)>::overload == call_free,+    typename call_traits<S&, void(const R&)>::result_type+  >::type+  operator()(S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(const R&)>::is_noexcept))+  {+    return connect(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(const R&)>::overload == call_free,+    typename call_traits<const S&, void(const R&)>::result_type+  >::type+  operator()(const S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(const R&)>::is_noexcept))+  {+    return connect(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(const R&)>::overload == adapter,+    typename call_traits<S&, void(const R&)>::result_type+  >::type+  operator()(S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(const R&)>::is_noexcept))+  {+    return typename call_traits<S&, void(const R&)>::result_type(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(const R&)>::overload == adapter,+    typename call_traits<const S&, void(const R&)>::result_type+  >::type+  operator()(const S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(const R&)>::is_noexcept))+  {+    return typename call_traits<const S&, void(const R&)>::result_type(s, r);+  }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+  static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_connect_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_connect_fn::impl&+  connect = asio_execution_connect_fn::static_instance<>::instance;++} // namespace++template <typename S, typename R>+struct can_connect :+  integral_constant<bool,+    asio_execution_connect_fn::call_traits<S, void(R)>::overload !=+      asio_execution_connect_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+constexpr bool can_connect_v = can_connect<S, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+struct is_nothrow_connect :+  integral_constant<bool,+    asio_execution_connect_fn::call_traits<S, void(R)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+constexpr bool is_nothrow_connect_v+  = is_nothrow_connect<S, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+struct connect_result+{+  typedef typename asio_execution_connect_fn::call_traits<+      S, void(R)>::result_type type;+};++#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename S, typename R>+using connect_result_t = typename connect_result<S, R>::type;++#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_CONNECT_HPP
link/modules/asio-standalone/asio/include/asio/execution/context.hpp view
@@ -2,7 +2,7 @@ // execution/context.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/traits/query_static_constexpr_member.hpp" #include "asio/traits/static_query.hpp"@@ -38,9 +40,10 @@ /// with an executor. struct context_t {-  /// The context_t property applies to executors.+  /// The context_t property applies to executors, senders, and schedulers.   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor_v<T>;+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;    /// The context_t property cannot be required.   static constexpr bool is_requirable = false;@@ -66,18 +69,38 @@ struct context_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = false;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);  #if defined(ASIO_HAS_STD_ANY)   typedef std::any polymorphic_query_result_type; #endif // defined(ASIO_HAS_STD_ANY) -  constexpr context_t()+  ASIO_CONSTEXPR context_t()   {   } @@ -88,17 +111,17 @@     struct type     {       template <typename P>-      static constexpr auto query(P&& p)+      static constexpr auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            conditional_t<true, T, P>::query(static_cast<P&&>(p))+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          conditional_t<true, T, P>::query(static_cast<P&&>(p))+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))         )       {-        return T::query(static_cast<P&&>(p));+        return T::query(ASIO_MOVE_CAST(P)(p));       }     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -114,17 +137,24 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(context_t::static_query<E>())>-  static constexpr const T static_query_v = context_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = context_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_CONSTEXPR)+  static const context_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR) };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -134,11 +164,20 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR)+template <int I>+const context_t<I> context_t<I>::instance;+#endif+ } // namespace detail  typedef detail::context_t<> context_t; -ASIO_INLINE_VARIABLE constexpr context_t context;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr context_t context;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const context_t& context = context_t::instance; }+#endif  } // namespace execution @@ -146,7 +185,21 @@  template <typename T> struct is_applicable_property<T, execution::context_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { }; @@ -159,18 +212,18 @@  template <typename T> struct static_query<T, execution::context_t,-  enable_if_t<+  typename enable_if<     execution::detail::context_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::context_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::context_t<0>::       query_static_constexpr_member<T>::value();
link/modules/asio-standalone/asio/include/asio/execution/context_as.hpp view
@@ -2,7 +2,7 @@ // execution/context_as.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,6 +19,8 @@ #include "asio/detail/type_traits.hpp" #include "asio/execution/context.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/query.hpp" #include "asio/traits/query_static_constexpr_member.hpp"@@ -37,9 +39,10 @@ template <typename U> struct context_as_t {-  /// The context_as_t property applies to executors.+  /// The context_as_t property applies to executors, senders, and schedulers.   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor_v<T>;+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;    /// The context_t property cannot be required.   static constexpr bool is_requirable = false;@@ -65,54 +68,77 @@ struct context_as_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename U>-  static constexpr bool is_applicable_property_v = is_executor<U>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<U>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename U>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<U>::value+        || conditional<+            is_executor<U>::value,+            false_type,+            is_sender<U>+          >::type::value+        || conditional<+            is_executor<U>::value,+            false_type,+            is_scheduler<U>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = false;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);    typedef T polymorphic_query_result_type; -  constexpr context_as_t()+  ASIO_CONSTEXPR context_as_t()   {   } -  constexpr context_as_t(context_t)+  ASIO_CONSTEXPR context_as_t(context_t)   {   }  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename E>-  static constexpr+  static ASIO_CONSTEXPR   typename context_t::query_static_constexpr_member<E>::result_type   static_query()-    noexcept(context_t::query_static_constexpr_member<E>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      context_t::query_static_constexpr_member<E>::is_noexcept))   {     return context_t::query_static_constexpr_member<E>::value();   }    template <typename E, typename U = decltype(context_as_t::static_query<E>())>-  static constexpr const U static_query_v+  static ASIO_CONSTEXPR const U static_query_v     = context_as_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)    template <typename Executor, typename U>-  friend constexpr U query(+  friend ASIO_CONSTEXPR U query(       const Executor& ex, const context_as_t<U>&,-      enable_if_t<+      typename enable_if<         is_same<T, U>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_query<const Executor&, const context_t&>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&, const context_t&>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, const context_t&>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, const context_t&>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, const context_t&>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -127,11 +153,13 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -#if defined(ASIO_HAS_VARIABLE_TEMPLATES) \+#if (defined(ASIO_HAS_VARIABLE_TEMPLATES) \+    && defined(ASIO_HAS_CONSTEXPR)) \   || defined(GENERATING_DOCUMENTATION) template <typename T> constexpr context_as_t<T> context_as{};-#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)+#endif // (defined(ASIO_HAS_VARIABLE_TEMPLATES)+       //     && defined(ASIO_HAS_CONSTEXPR))        //   || defined(GENERATING_DOCUMENTATION)  } // namespace execution@@ -139,8 +167,22 @@ #if !defined(ASIO_HAS_VARIABLE_TEMPLATES)  template <typename T, typename U>-struct is_applicable_property<T, execution::context_as_t<U>>-  : integral_constant<bool, execution::is_executor<T>::value>+struct is_applicable_property<T, execution::context_as_t<U> >+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { }; @@ -153,9 +195,9 @@  template <typename T, typename U> struct static_query<T, execution::context_as_t<U>,-  enable_if_t<+  typename enable_if<     static_query<T, execution::context_t>::is_valid-  >> : static_query<T, execution::context_t>+  >::type> : static_query<T, execution::context_t> { }; @@ -166,13 +208,13 @@  template <typename T, typename U> struct query_free<T, execution::context_as_t<U>,-  enable_if_t<-    can_query<const T&, const execution::context_t&>::value-  >>+    typename enable_if<+      can_query<const T&, const execution::context_t&>::value+    >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<const T&, const execution::context_t&>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<const T&, const execution::context_t&>::value));    typedef U result_type; };
+ link/modules/asio-standalone/asio/include/asio/execution/detail/as_invocable.hpp view
@@ -0,0 +1,152 @@+//+// execution/detail/as_invocable.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_DETAIL_AS_INVOCABLE_HPP+#define ASIO_EXECUTION_DETAIL_AS_INVOCABLE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/atomic_count.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/execution/receiver_invocation_error.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++#if defined(ASIO_HAS_MOVE)++template <typename Receiver, typename>+struct as_invocable+{+  Receiver* receiver_;++  explicit as_invocable(Receiver& r) ASIO_NOEXCEPT+    : receiver_(asio::detail::addressof(r))+  {+  }++  as_invocable(as_invocable&& other) ASIO_NOEXCEPT+    : receiver_(other.receiver_)+  {+    other.receiver_ = 0;+  }++  ~as_invocable()+  {+    if (receiver_)+      execution::set_done(ASIO_MOVE_OR_LVALUE(Receiver)(*receiver_));+  }++  void operator()() ASIO_LVALUE_REF_QUAL ASIO_NOEXCEPT+  {+#if !defined(ASIO_NO_EXCEPTIONS)+    try+    {+#endif // !defined(ASIO_NO_EXCEPTIONS)+      execution::set_value(ASIO_MOVE_CAST(Receiver)(*receiver_));+      receiver_ = 0;+#if !defined(ASIO_NO_EXCEPTIONS)+    }+    catch (...)+    {+#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+      execution::set_error(ASIO_MOVE_CAST(Receiver)(*receiver_),+          std::make_exception_ptr(receiver_invocation_error()));+      receiver_ = 0;+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+      std::terminate();+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+    }+#endif // !defined(ASIO_NO_EXCEPTIONS)+  }+};++#else // defined(ASIO_HAS_MOVE)++template <typename Receiver, typename>+struct as_invocable+{+  Receiver* receiver_;+  asio::detail::shared_ptr<asio::detail::atomic_count> ref_count_;++  explicit as_invocable(Receiver& r,+      const asio::detail::shared_ptr<+        asio::detail::atomic_count>& c) ASIO_NOEXCEPT+    : receiver_(asio::detail::addressof(r)),+      ref_count_(c)+  {+  }++  as_invocable(const as_invocable& other) ASIO_NOEXCEPT+    : receiver_(other.receiver_),+      ref_count_(other.ref_count_)+  {+    ++(*ref_count_);+  }++  ~as_invocable()+  {+    if (--(*ref_count_) == 0)+      execution::set_done(*receiver_);+  }++  void operator()() ASIO_LVALUE_REF_QUAL ASIO_NOEXCEPT+  {+#if !defined(ASIO_NO_EXCEPTIONS)+    try+    {+#endif // !defined(ASIO_NO_EXCEPTIONS)+      execution::set_value(*receiver_);+      ++(*ref_count_);+    }+#if !defined(ASIO_NO_EXCEPTIONS)+    catch (...)+    {+#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+      execution::set_error(*receiver_,+          std::make_exception_ptr(receiver_invocation_error()));+      ++(*ref_count_);+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+      std::terminate();+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+    }+#endif // !defined(ASIO_NO_EXCEPTIONS)+  }+};++#endif // defined(ASIO_HAS_MOVE)++template <typename T>+struct is_as_invocable : false_type+{+};++template <typename Function, typename T>+struct is_as_invocable<as_invocable<Function, T> > : true_type+{+};++} // namespace detail+} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_AS_INVOCABLE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/as_operation.hpp view
@@ -0,0 +1,109 @@+//+// execution/detail/as_operation.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_DETAIL_AS_OPERATION_HPP+#define ASIO_EXECUTION_DETAIL_AS_OPERATION_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/as_invocable.hpp"+#include "asio/execution/execute.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/traits/start_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename Executor, typename Receiver>+struct as_operation+{+  typename remove_cvref<Executor>::type ex_;+  typename remove_cvref<Receiver>::type receiver_;+#if !defined(ASIO_HAS_MOVE)+  asio::detail::shared_ptr<asio::detail::atomic_count> ref_count_;+#endif // !defined(ASIO_HAS_MOVE)++  template <typename E, typename R>+  explicit as_operation(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(R) r)+    : ex_(ASIO_MOVE_CAST(E)(e)),+      receiver_(ASIO_MOVE_CAST(R)(r))+#if !defined(ASIO_HAS_MOVE)+      , ref_count_(new asio::detail::atomic_count(1))+#endif // !defined(ASIO_HAS_MOVE)+  {+  }++  void start() ASIO_NOEXCEPT+  {+#if !defined(ASIO_NO_EXCEPTIONS)+    try+    {+#endif // !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_NO_DEPRECATED)+      ex_.execute(+#else // defined(ASIO_NO_DEPRECATED)+      execution::execute(+          ASIO_MOVE_CAST(typename remove_cvref<Executor>::type)(ex_),+#endif // defined(ASIO_NO_DEPRECATED)+          as_invocable<typename remove_cvref<Receiver>::type,+              Executor>(receiver_+#if !defined(ASIO_HAS_MOVE)+                , ref_count_+#endif // !defined(ASIO_HAS_MOVE)+              ));+#if !defined(ASIO_NO_EXCEPTIONS)+    }+    catch (...)+    {+#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+      execution::set_error(+          ASIO_MOVE_OR_LVALUE(+            typename remove_cvref<Receiver>::type)(+              receiver_),+          std::current_exception());+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+      std::terminate();+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+    }+#endif // !defined(ASIO_NO_EXCEPTIONS)+  }+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++template <typename Executor, typename Receiver>+struct start_member<+    asio::execution::detail::as_operation<Executor, Receiver> >+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_AS_OPERATION_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/as_receiver.hpp view
@@ -0,0 +1,128 @@+//+// execution/detail/as_receiver.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_DETAIL_AS_RECEIVER_HPP+#define ASIO_EXECUTION_DETAIL_AS_RECEIVER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_value_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename Function, typename>+struct as_receiver+{+  Function f_;++  template <typename F>+  explicit as_receiver(ASIO_MOVE_ARG(F) f, int)+    : f_(ASIO_MOVE_CAST(F)(f))+  {+  }++#if defined(ASIO_MSVC) && defined(ASIO_HAS_MOVE)+  as_receiver(as_receiver&& other)+    : f_(ASIO_MOVE_CAST(Function)(other.f_))+  {+  }+#endif // defined(ASIO_MSVC) && defined(ASIO_HAS_MOVE)++  void set_value()+    ASIO_NOEXCEPT_IF(noexcept(declval<Function&>()()))+  {+    f_();+  }++  template <typename E>+  void set_error(E) ASIO_NOEXCEPT+  {+    std::terminate();+  }++  void set_done() ASIO_NOEXCEPT+  {+  }+};++template <typename T>+struct is_as_receiver : false_type+{+};++template <typename Function, typename T>+struct is_as_receiver<as_receiver<Function, T> > : true_type+{+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <typename Function, typename T>+struct set_value_member<+    asio::execution::detail::as_receiver<Function, T>, void()>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+#if defined(ASIO_HAS_NOEXCEPT)+  ASIO_STATIC_CONSTEXPR(bool,+      is_noexcept = noexcept(declval<Function&>()()));+#else // defined(ASIO_HAS_NOEXCEPT)+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+#endif // defined(ASIO_HAS_NOEXCEPT)+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename Function, typename T, typename E>+struct set_error_member<+    asio::execution::detail::as_receiver<Function, T>, E>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename Function, typename T>+struct set_done_member<+    asio::execution::detail::as_receiver<Function, T> >+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_AS_RECEIVER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/bulk_sender.hpp view
@@ -0,0 +1,261 @@+//+// execution/detail/bulk_sender.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP+#define ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/execution/connect.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/traits/connect_member.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_value_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename Receiver, typename Function, typename Number, typename Index>+struct bulk_receiver+{+  typename remove_cvref<Receiver>::type receiver_;+  typename decay<Function>::type f_;+  typename decay<Number>::type n_;++  template <typename R, typename F, typename N>+  explicit bulk_receiver(ASIO_MOVE_ARG(R) r,+      ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(N) n)+    : receiver_(ASIO_MOVE_CAST(R)(r)),+      f_(ASIO_MOVE_CAST(F)(f)),+      n_(ASIO_MOVE_CAST(N)(n))+  {+  }++  void set_value()+  {+    for (Index i = 0; i < n_; ++i)+      f_(i);++    execution::set_value(+        ASIO_MOVE_OR_LVALUE(+          typename remove_cvref<Receiver>::type)(receiver_));+  }++  template <typename Error>+  void set_error(ASIO_MOVE_ARG(Error) e) ASIO_NOEXCEPT+  {+    execution::set_error(+        ASIO_MOVE_OR_LVALUE(+          typename remove_cvref<Receiver>::type)(receiver_),+        ASIO_MOVE_CAST(Error)(e));+  }++  void set_done() ASIO_NOEXCEPT+  {+    execution::set_done(+        ASIO_MOVE_OR_LVALUE(+          typename remove_cvref<Receiver>::type)(receiver_));+  }+};++template <typename Sender, typename Receiver,+  typename Function, typename Number>+struct bulk_receiver_traits+{+  typedef bulk_receiver<+      Receiver, Function, Number,+      typename execution::executor_index<+        typename remove_cvref<Sender>::type+      >::type+    > type;++#if defined(ASIO_HAS_MOVE)+  typedef type arg_type;+#else // defined(ASIO_HAS_MOVE)+  typedef const type& arg_type;+#endif // defined(ASIO_HAS_MOVE)+};++template <typename Sender, typename Function, typename Number>+struct bulk_sender : sender_base+{+  typename remove_cvref<Sender>::type sender_;+  typename decay<Function>::type f_;+  typename decay<Number>::type n_;++  template <typename S, typename F, typename N>+  explicit bulk_sender(ASIO_MOVE_ARG(S) s,+      ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(N) n)+    : sender_(ASIO_MOVE_CAST(S)(s)),+      f_(ASIO_MOVE_CAST(F)(f)),+      n_(ASIO_MOVE_CAST(N)(n))+  {+  }++  template <typename Receiver>+  typename connect_result<+      ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type),+      typename bulk_receiver_traits<+        Sender, Receiver, Function, Number+      >::arg_type+  >::type connect(ASIO_MOVE_ARG(Receiver) r,+      typename enable_if<+        can_connect<+          typename remove_cvref<Sender>::type,+          typename bulk_receiver_traits<+            Sender, Receiver, Function, Number+          >::arg_type+        >::value+      >::type* = 0) ASIO_RVALUE_REF_QUAL ASIO_NOEXCEPT+  {+    return execution::connect(+        ASIO_MOVE_OR_LVALUE(typename remove_cvref<Sender>::type)(sender_),+        typename bulk_receiver_traits<Sender, Receiver, Function, Number>::type(+          ASIO_MOVE_CAST(Receiver)(r),+          ASIO_MOVE_CAST(typename decay<Function>::type)(f_),+          ASIO_MOVE_CAST(typename decay<Number>::type)(n_)));+  }++  template <typename Receiver>+  typename connect_result<+      const typename remove_cvref<Sender>::type&,+      typename bulk_receiver_traits<+        Sender, Receiver, Function, Number+      >::arg_type+  >::type connect(ASIO_MOVE_ARG(Receiver) r,+      typename enable_if<+        can_connect<+          const typename remove_cvref<Sender>::type&,+          typename bulk_receiver_traits<+            Sender, Receiver, Function, Number+          >::arg_type+        >::value+      >::type* = 0) const ASIO_LVALUE_REF_QUAL ASIO_NOEXCEPT+  {+    return execution::connect(sender_,+        typename bulk_receiver_traits<Sender, Receiver, Function, Number>::type(+          ASIO_MOVE_CAST(Receiver)(r), f_, n_));+  }+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <typename Receiver, typename Function, typename Number, typename Index>+struct set_value_member<+    execution::detail::bulk_receiver<Receiver, Function, Number, Index>,+    void()>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename Receiver, typename Function,+    typename Number, typename Index, typename Error>+struct set_error_member<+    execution::detail::bulk_receiver<Receiver, Function, Number, Index>,+    Error>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename Receiver, typename Function, typename Number, typename Index>+struct set_done_member<+    execution::detail::bulk_receiver<Receiver, Function, Number, Index> >+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++template <typename Sender, typename Function,+    typename Number, typename Receiver>+struct connect_member<+    execution::detail::bulk_sender<Sender, Function, Number>,+    Receiver,+    typename enable_if<+      execution::can_connect<+        ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type),+        typename execution::detail::bulk_receiver_traits<+          Sender, Receiver, Function, Number+        >::arg_type+      >::value+    >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef typename execution::connect_result<+      ASIO_MOVE_OR_LVALUE_TYPE(typename remove_cvref<Sender>::type),+      typename execution::detail::bulk_receiver_traits<+        Sender, Receiver, Function, Number+      >::arg_type+    >::type result_type;+};++template <typename Sender, typename Function,+    typename Number, typename Receiver>+struct connect_member<+    const execution::detail::bulk_sender<Sender, Function, Number>,+    Receiver,+    typename enable_if<+      execution::can_connect<+        const typename remove_cvref<Sender>::type&,+        typename execution::detail::bulk_receiver_traits<+          Sender, Receiver, Function, Number+        >::arg_type+      >::value+    >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef typename execution::connect_result<+      const typename remove_cvref<Sender>::type&,+      typename execution::detail::bulk_receiver_traits<+        Sender, Receiver, Function, Number+      >::arg_type+    >::type result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_BULK_SENDER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/submit_receiver.hpp view
@@ -0,0 +1,233 @@+//+// execution/detail/submit_receiver.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_DETAIL_SUBMIT_RECEIVER_HPP+#define ASIO_EXECUTION_DETAIL_SUBMIT_RECEIVER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"+#include "asio/execution/connect.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_value_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename Sender, typename Receiver>+struct submit_receiver;++template <typename Sender, typename Receiver>+struct submit_receiver_wrapper+{+  submit_receiver<Sender, Receiver>* p_;++  explicit submit_receiver_wrapper(submit_receiver<Sender, Receiver>* p)+    : p_(p)+  {+  }++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename... Args>+  typename enable_if<is_receiver_of<Receiver, Args...>::value>::type+  set_value(ASIO_MOVE_ARG(Args)... args) ASIO_RVALUE_REF_QUAL+    ASIO_NOEXCEPT_IF((is_nothrow_receiver_of<Receiver, Args...>::value))+  {+    execution::set_value(+        ASIO_MOVE_OR_LVALUE(+          typename remove_cvref<Receiver>::type)(p_->r_),+        ASIO_MOVE_CAST(Args)(args)...);+    delete p_;+  }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  void set_value() ASIO_RVALUE_REF_QUAL+    ASIO_NOEXCEPT_IF((is_nothrow_receiver_of<Receiver>::value))+  {+    execution::set_value(+        ASIO_MOVE_OR_LVALUE(+          typename remove_cvref<Receiver>::type)(p_->r_));+    delete p_;+  }++#define ASIO_PRIVATE_SUBMIT_RECEIVER_SET_VALUE_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  typename enable_if<is_receiver_of<Receiver, \+    ASIO_VARIADIC_TARGS(n)>::value>::type \+  set_value(ASIO_VARIADIC_MOVE_PARAMS(n)) ASIO_RVALUE_REF_QUAL \+    ASIO_NOEXCEPT_IF((is_nothrow_receiver_of< \+      Receiver, ASIO_VARIADIC_TARGS(n)>::value)) \+  { \+    execution::set_value( \+        ASIO_MOVE_OR_LVALUE( \+          typename remove_cvref<Receiver>::type)(p_->r_), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+    delete p_; \+  } \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SUBMIT_RECEIVER_SET_VALUE_DEF)+#undef ASIO_PRIVATE_SUBMIT_RECEIVER_SET_VALUE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename E>+  void set_error(ASIO_MOVE_ARG(E) e)+    ASIO_RVALUE_REF_QUAL ASIO_NOEXCEPT+  {+    execution::set_error(+        ASIO_MOVE_OR_LVALUE(+          typename remove_cvref<Receiver>::type)(p_->r_),+        ASIO_MOVE_CAST(E)(e));+    delete p_;+  }++  void set_done() ASIO_RVALUE_REF_QUAL ASIO_NOEXCEPT+  {+    execution::set_done(+        ASIO_MOVE_OR_LVALUE(+          typename remove_cvref<Receiver>::type)(p_->r_));+    delete p_;+  }+};++template <typename Sender, typename Receiver>+struct submit_receiver+{+  typename remove_cvref<Receiver>::type r_;+#if defined(ASIO_HAS_MOVE)+  typename connect_result<Sender,+      submit_receiver_wrapper<Sender, Receiver> >::type state_;+#else // defined(ASIO_HAS_MOVE)+  typename connect_result<Sender,+      const submit_receiver_wrapper<Sender, Receiver>& >::type state_;+#endif // defined(ASIO_HAS_MOVE)++#if defined(ASIO_HAS_MOVE)+  template <typename S, typename R>+  explicit submit_receiver(ASIO_MOVE_ARG(S) s, ASIO_MOVE_ARG(R) r)+    : r_(ASIO_MOVE_CAST(R)(r)),+      state_(execution::connect(ASIO_MOVE_CAST(S)(s),+            submit_receiver_wrapper<Sender, Receiver>(this)))+  {+  }+#else // defined(ASIO_HAS_MOVE)+  explicit submit_receiver(Sender s, Receiver r)+    : r_(r),+      state_(execution::connect(s,+            submit_receiver_wrapper<Sender, Receiver>(this)))+  {+  }+#endif // defined(ASIO_HAS_MOVE)+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Sender, typename Receiver, typename... Args>+struct set_value_member<+    asio::execution::detail::submit_receiver_wrapper<+      Sender, Receiver>,+    void(Args...)>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (asio::execution::is_nothrow_receiver_of<Receiver, Args...>::value));+  typedef void result_type;+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Sender, typename Receiver>+struct set_value_member<+    asio::execution::detail::submit_receiver_wrapper<+      Sender, Receiver>,+    void()>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    asio::execution::is_nothrow_receiver_of<Receiver>::value);+  typedef void result_type;+};++#define ASIO_PRIVATE_SUBMIT_RECEIVER_TRAIT_DEF(n) \+  template <typename Sender, typename Receiver, \+      ASIO_VARIADIC_TPARAMS(n)> \+  struct set_value_member< \+      asio::execution::detail::submit_receiver_wrapper< \+        Sender, Receiver>, \+      void(ASIO_VARIADIC_TARGS(n))> \+  { \+    ASIO_STATIC_CONSTEXPR(bool, is_valid = true); \+    ASIO_STATIC_CONSTEXPR(bool, is_noexcept = \+      (asio::execution::is_nothrow_receiver_of<Receiver, \+        ASIO_VARIADIC_TARGS(n)>::value)); \+    typedef void result_type; \+  }; \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SUBMIT_RECEIVER_TRAIT_DEF)+#undef ASIO_PRIVATE_SUBMIT_RECEIVER_TRAIT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename Sender, typename Receiver, typename E>+struct set_error_member<+    asio::execution::detail::submit_receiver_wrapper<+      Sender, Receiver>, E>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename Sender, typename Receiver>+struct set_done_member<+    asio::execution::detail::submit_receiver_wrapper<+      Sender, Receiver> >+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_SUBMIT_RECEIVER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/detail/void_receiver.hpp view
@@ -0,0 +1,90 @@+//+// execution/detail/void_receiver.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_DETAIL_VOID_RECEIVER_HPP+#define ASIO_EXECUTION_DETAIL_VOID_RECEIVER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_value_member.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++struct void_receiver+{+  void set_value() ASIO_NOEXCEPT+  {+  }++  template <typename E>+  void set_error(ASIO_MOVE_ARG(E)) ASIO_NOEXCEPT+  {+  }++  void set_done() ASIO_NOEXCEPT+  {+  }+};++} // namespace detail+} // namespace execution+namespace traits {++#if !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <>+struct set_value_member<asio::execution::detail::void_receiver, void()>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename E>+struct set_error_member<asio::execution::detail::void_receiver, E>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <>+struct set_done_member<asio::execution::detail::void_receiver>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef void result_type;+};++#endif // !defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_DETAIL_VOID_RECEIVER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/execute.hpp view
@@ -0,0 +1,290 @@+//+// execution/execute.hpp+// ~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_EXECUTE_HPP+#define ASIO_EXECUTION_EXECUTE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/as_invocable.hpp"+#include "asio/execution/detail/as_receiver.hpp"+#include "asio/traits/execute_member.hpp"+#include "asio/traits/execute_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// (Deprecated: Use @c execute member function.) A customisation point that+/// executes a function on an executor.+/**+ * The name <tt>execution::execute</tt> denotes a customisation point object.+ *+ * For some subexpressions <tt>e</tt> and <tt>f</tt>, let <tt>E</tt> be a type+ * such that <tt>decltype((e))</tt> is <tt>E</tt> and let <tt>F</tt> be a type+ * such that <tt>decltype((f))</tt> is <tt>F</tt>. The expression+ * <tt>execution::execute(e, f)</tt> is ill-formed if <tt>F</tt> does not model+ * <tt>invocable</tt>, or if <tt>E</tt> does not model either <tt>executor</tt>+ * or <tt>sender</tt>. Otherwise, it is expression-equivalent to:+ *+ * @li <tt>e.execute(f)</tt>, if that expression is valid. If the function+ *   selected does not execute the function object <tt>f</tt> on the executor+ *   <tt>e</tt>, the program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>execute(e, f)</tt>, if that expression is valid, with+ *   overload resolution performed in a context that includes the declaration+ *   <tt>void execute();</tt> and that does not include a declaration of+ *   <tt>execution::execute</tt>. If the function selected by overload+ *   resolution does not execute the function object <tt>f</tt> on the executor+ *   <tt>e</tt>, the program is ill-formed with no diagnostic required.+ */+inline constexpr unspecified execute = unspecified;++/// (Deprecated.) A type trait that determines whether an @c execute expression+/// is well-formed.+/**+ * Class template @c can_execute is a trait that is derived from+ * @c true_type if the expression <tt>execution::execute(std::declval<T>(),+ * std::declval<F>())</tt> is well formed; otherwise @c false_type.+ */+template <typename T, typename F>+struct can_execute :+  integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++template <typename T, typename R>+struct is_sender_to;++namespace detail {++template <typename S, typename R>+void submit_helper(ASIO_MOVE_ARG(S) s, ASIO_MOVE_ARG(R) r);++} // namespace detail+} // namespace execution+} // namespace asio+namespace asio_execution_execute_fn {++using asio::conditional;+using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::execution::detail::as_receiver;+using asio::execution::detail::is_as_invocable;+using asio::execution::is_sender_to;+using asio::false_type;+using asio::result_of;+using asio::traits::execute_free;+using asio::traits::execute_member;+using asio::true_type;+using asio::void_type;++void execute();++enum overload_type+{+  call_member,+  call_free,+  adapter,+  ill_formed+};++template <typename Impl, typename T, typename F, typename = void,+    typename = void, typename = void, typename = void, typename = void>+struct call_traits+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+};++template <typename Impl, typename T, typename F>+struct call_traits<Impl, T, void(F),+  typename enable_if<+    execute_member<typename Impl::template proxy<T>::type, F>::is_valid+  >::type> :+  execute_member<typename Impl::template proxy<T>::type, F>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename Impl, typename T, typename F>+struct call_traits<Impl, T, void(F),+  typename enable_if<+    !execute_member<typename Impl::template proxy<T>, F>::is_valid+  >::type,+  typename enable_if<+    execute_free<T, F>::is_valid+  >::type> :+  execute_free<T, F>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename Impl, typename T, typename F>+struct call_traits<Impl, T, void(F),+  typename enable_if<+    !execute_member<typename Impl::template proxy<T>::type, F>::is_valid+  >::type,+  typename enable_if<+    !execute_free<T, F>::is_valid+  >::type,+  typename void_type<+   typename result_of<typename decay<F>::type&()>::type+  >::type,+  typename enable_if<+    !is_as_invocable<typename decay<F>::type>::value+  >::type,+  typename enable_if<+    is_sender_to<T, as_receiver<typename decay<F>::type, T> >::value+  >::type>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++struct impl+{+  template <typename T>+  struct proxy+  {+#if defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+    struct type+    {+      template <typename F>+      auto execute(ASIO_MOVE_ARG(F) f)+        noexcept(+          noexcept(+            declval<typename conditional<true, T, F>::type>().execute(+              ASIO_MOVE_CAST(F)(f))+          )+        )+        -> decltype(+          declval<typename conditional<true, T, F>::type>().execute(+            ASIO_MOVE_CAST(F)(f))+        );+    };+#else // defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+    typedef T type;+#endif // defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+  };++  template <typename T, typename F>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<impl, T, void(F)>::overload == call_member,+    typename call_traits<impl, T, void(F)>::result_type+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(F) f) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(F)>::is_noexcept))+  {+    return ASIO_MOVE_CAST(T)(t).execute(ASIO_MOVE_CAST(F)(f));+  }++  template <typename T, typename F>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<impl, T, void(F)>::overload == call_free,+    typename call_traits<impl, T, void(F)>::result_type+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(F) f) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(F)>::is_noexcept))+  {+    return execute(ASIO_MOVE_CAST(T)(t), ASIO_MOVE_CAST(F)(f));+  }++  template <typename T, typename F>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<impl, T, void(F)>::overload == adapter,+    typename call_traits<impl, T, void(F)>::result_type+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(F) f) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(F)>::is_noexcept))+  {+    return asio::execution::detail::submit_helper(+        ASIO_MOVE_CAST(T)(t),+        as_receiver<typename decay<F>::type, T>(+          ASIO_MOVE_CAST(F)(f), 0));+  }+};++template <typename T = impl>+struct static_instance+{+  static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_execute_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_execute_fn::impl&+  execute = asio_execution_execute_fn::static_instance<>::instance;++} // namespace++typedef asio_execution_execute_fn::impl execute_t;++template <typename T, typename F>+struct can_execute :+  integral_constant<bool,+    asio_execution_execute_fn::call_traits<+      execute_t, T, void(F)>::overload !=+        asio_execution_execute_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename F>+constexpr bool can_execute_v = can_execute<T, F>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_EXECUTE_HPP
link/modules/asio-standalone/asio/include/asio/execution/executor.hpp view
@@ -2,7 +2,7 @@ // execution/executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,10 +21,16 @@ #include "asio/traits/equality_comparable.hpp" #include "asio/traits/execute_member.hpp" -#if defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) \+#if !defined(ASIO_NO_DEPRECATED)+# include "asio/execution/execute.hpp"+#endif // !defined(ASIO_NO_DEPRECATED)++#if defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT) \+  && defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) \   && defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) # define ASIO_HAS_DEDUCED_EXECUTION_IS_EXECUTOR_TRAIT 1-#endif // defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)+#endif // defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)+       //   && defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)        //   && defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)  #include "asio/detail/push_options.hpp"@@ -42,33 +48,78 @@  template <typename T, typename F> struct is_executor_of_impl<T, F,-  enable_if_t<-    traits::execute_member<add_const_t<T>, F>::is_valid-  >,-  void_t<-    result_of_t<decay_t<F>&()>-  >,-  enable_if_t<-    is_constructible<decay_t<F>, F>::value-  >,-  enable_if_t<-    is_move_constructible<decay_t<F>>::value-  >,-  enable_if_t<+#if defined(ASIO_NO_DEPRECATED)+  typename enable_if<+    traits::execute_member<typename add_const<T>::type, F>::is_valid+  >::type,+#else // defined(ASIO_NO_DEPRECATED)+  typename enable_if<+    can_execute<typename add_const<T>::type, F>::value+  >::type,+#endif // defined(ASIO_NO_DEPRECATED)+  typename void_type<+    typename result_of<typename decay<F>::type&()>::type+  >::type,+  typename enable_if<+    is_constructible<typename decay<F>::type, F>::value+  >::type,+  typename enable_if<+    is_move_constructible<typename decay<F>::type>::value+  >::type,+#if defined(ASIO_HAS_NOEXCEPT)+  typename enable_if<     is_nothrow_copy_constructible<T>::value-  >,-  enable_if_t<+  >::type,+  typename enable_if<     is_nothrow_destructible<T>::value-  >,-  enable_if_t<+  >::type,+#else // defined(ASIO_HAS_NOEXCEPT)+  typename enable_if<+    is_copy_constructible<T>::value+  >::type,+  typename enable_if<+    is_destructible<T>::value+  >::type,+#endif // defined(ASIO_HAS_NOEXCEPT)+  typename enable_if<     traits::equality_comparable<T>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     traits::equality_comparable<T>::is_noexcept-  >> : true_type+  >::type> : true_type { }; +template <typename T, typename = void>+struct executor_shape+{+  typedef std::size_t type;+};++template <typename T>+struct executor_shape<T,+    typename void_type<+      typename T::shape_type+    >::type>+{+  typedef typename T::shape_type type;+};++template <typename T, typename Default, typename = void>+struct executor_index+{+  typedef Default type;+};++template <typename T, typename Default>+struct executor_index<T, Default,+    typename void_type<+      typename T::index_type+    >::type>+{+  typedef typename T::index_type type;+};+ } // namespace detail  /// The is_executor trait detects whether a type T satisfies the@@ -91,7 +142,7 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES)  template <typename T>-constexpr const bool is_executor_v = is_executor<T>::value;+ASIO_CONSTEXPR const bool is_executor_v = is_executor<T>::value;  #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) @@ -107,6 +158,101 @@ #define ASIO_EXECUTION_EXECUTOR typename  #endif // defined(ASIO_HAS_CONCEPTS)++/// The is_executor_of trait detects whether a type T satisfies the+/// execution::executor_of concept for some set of value arguments.+/**+ * Class template @c is_executor_of is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for an executor+ * that is invocable with a function object of type @c F, otherwise @c+ * false_type.+ */+template <typename T, typename F>+struct is_executor_of :+#if defined(GENERATING_DOCUMENTATION)+  integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  integral_constant<bool,+    is_executor<T>::value && detail::is_executor_of_impl<T, F>::value+  >+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename F>+ASIO_CONSTEXPR const bool is_executor_of_v =+  is_executor_of<T, F>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T, typename F>+ASIO_CONCEPT executor_of = is_executor_of<T, F>::value;++#define ASIO_EXECUTION_EXECUTOR_OF(f) \+  ::asio::execution::executor_of<f>++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_EXECUTOR_OF typename++#endif // defined(ASIO_HAS_CONCEPTS)++/// The executor_shape trait detects the type used by an executor to represent+/// the shape of a bulk operation.+/**+ * Class template @c executor_shape is a type trait with a nested type alias+ * @c type whose type is @c T::shape_type if @c T::shape_type is valid,+ * otherwise @c std::size_t.+ */+template <typename T>+struct executor_shape+#if !defined(GENERATING_DOCUMENTATION)+  : detail::executor_shape<T>+#endif // !defined(GENERATING_DOCUMENTATION)+{+#if defined(GENERATING_DOCUMENTATION)+ /// @c T::shape_type if @c T::shape_type is valid, otherwise @c std::size_t.+ typedef automatically_determined type;+#endif // defined(GENERATING_DOCUMENTATION)+};++#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename T>+using executor_shape_t = typename executor_shape<T>::type;++#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)++/// The executor_index trait detects the type used by an executor to represent+/// an index within a bulk operation.+/**+ * Class template @c executor_index is a type trait with a nested type alias+ * @c type whose type is @c T::index_type if @c T::index_type is valid,+ * otherwise @c executor_shape_t<T>.+ */+template <typename T>+struct executor_index+#if !defined(GENERATING_DOCUMENTATION)+  : detail::executor_index<T, typename executor_shape<T>::type>+#endif // !defined(GENERATING_DOCUMENTATION)+{+#if defined(GENERATING_DOCUMENTATION)+ /// @c T::index_type if @c T::index_type is valid, otherwise+ /// @c executor_shape_t<T>.+ typedef automatically_determined type;+#endif // defined(GENERATING_DOCUMENTATION)+};++#if defined(ASIO_HAS_ALIAS_TEMPLATES)++template <typename T>+using executor_index_t = typename executor_index<T>::type;++#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)  } // namespace execution } // namespace asio
link/modules/asio-standalone/asio/include/asio/execution/impl/bad_executor.ipp view
@@ -1,8 +1,8 @@ //-// execution/impl/bad_executor.ipp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+// exection/impl/bad_executor.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,11 +23,11 @@ namespace asio { namespace execution { -bad_executor::bad_executor() noexcept+bad_executor::bad_executor() ASIO_NOEXCEPT { } -const char* bad_executor::what() const noexcept+const char* bad_executor::what() const ASIO_NOEXCEPT_OR_NOTHROW {   return "bad executor"; }
+ link/modules/asio-standalone/asio/include/asio/execution/impl/receiver_invocation_error.ipp view
@@ -0,0 +1,36 @@+//+// exection/impl/receiver_invocation_error.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_IMPL_RECEIVER_INVOCATION_ERROR_IPP+#define ASIO_EXECUTION_IMPL_RECEIVER_INVOCATION_ERROR_IPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/execution/receiver_invocation_error.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {++receiver_invocation_error::receiver_invocation_error()+  : std::runtime_error("receiver invocation error")+{+}++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXECUTION_IMPL_RECEIVER_INVOCATION_ERROR_IPP
link/modules/asio-standalone/asio/include/asio/execution/invocable_archetype.hpp view
@@ -2,7 +2,7 @@ // execution/invocable_archetype.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,6 +17,7 @@  #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp" @@ -27,11 +28,38 @@ /// execution::executor concept. struct invocable_archetype {+#if !defined(GENERATING_DOCUMENTATION)+  // Necessary for compatibility with a C++03 implementation of result_of.+  typedef void result_type;+#endif // !defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)+   /// Function call operator.   template <typename... Args>-  void operator()(Args&&...)+  void operator()(ASIO_MOVE_ARG(Args)...)   {   }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+      //   || defined(GENERATING_DOCUMENTATION)++  void operator()()+  {+  }++#define ASIO_PRIVATE_INVOCABLE_ARCHETYPE_CALL_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  void operator()(ASIO_VARIADIC_UNNAMED_MOVE_PARAMS(n)) \+  { \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INVOCABLE_ARCHETYPE_CALL_DEF)+#undef ASIO_PRIVATE_INVOCABLE_ARCHETYPE_CALL_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION) };  } // namespace execution
link/modules/asio-standalone/asio/include/asio/execution/mapping.hpp view
@@ -2,7 +2,7 @@ // execution/mapping.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/query.hpp" #include "asio/traits/query_free.hpp"@@ -38,9 +40,10 @@ /// of execution agents on to threads of execution. struct mapping_t {-  /// The mapping_t property applies to executors.+  /// The mapping_t property applies to executors, senders, and schedulers.   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor_v<T>;+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;    /// The top-level mapping_t property cannot be required.   static constexpr bool is_requirable = false;@@ -55,9 +58,11 @@   /// threads of execution.   struct thread_t   {-    /// The mapping_t::thread_t property applies to executors.+    /// The mapping_t::thread_t property applies to executors, senders, and+    /// schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The mapping_t::thread_t property can be required.     static constexpr bool is_requirable = true;@@ -82,9 +87,11 @@   /// new threads of execution.   struct new_thread_t   {-    /// The mapping_t::new_thread_t property applies to executors.+    /// The mapping_t::new_thread_t property applies to executors, senders, and+    /// schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The mapping_t::new_thread_t property can be required.     static constexpr bool is_requirable = true;@@ -109,9 +116,11 @@   /// implementation-defined.   struct other_t   {-    /// The mapping_t::other_t property applies to executors.+    /// The mapping_t::other_t property applies to executors, senders, and+    /// schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The mapping_t::other_t property can be required.     static constexpr bool is_requirable = true;@@ -183,34 +192,54 @@ struct mapping_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = false;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);   typedef mapping_t polymorphic_query_result_type;    typedef detail::mapping::thread_t<I> thread_t;   typedef detail::mapping::new_thread_t<I> new_thread_t;   typedef detail::mapping::other_t<I> other_t; -  constexpr mapping_t()+  ASIO_CONSTEXPR mapping_t()     : value_(-1)   {   } -  constexpr mapping_t(thread_t)+  ASIO_CONSTEXPR mapping_t(thread_t)     : value_(0)   {   } -  constexpr mapping_t(new_thread_t)+  ASIO_CONSTEXPR mapping_t(new_thread_t)     : value_(1)   {   } -  constexpr mapping_t(other_t)+  ASIO_CONSTEXPR mapping_t(other_t)     : value_(2)   {   }@@ -222,14 +251,16 @@     struct type     {       template <typename P>-      auto query(P&& p) const+      auto query(ASIO_MOVE_ARG(P) p) const         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().query(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().query(+            ASIO_MOVE_CAST(P)(p))         );     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -244,17 +275,17 @@     struct type     {       template <typename P>-      static constexpr auto query(P&& p)+      static constexpr auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            conditional_t<true, T, P>::query(static_cast<P&&>(p))+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          conditional_t<true, T, P>::query(static_cast<P&&>(p))+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))         )       {-        return T::query(static_cast<P&&>(p));+        return T::query(ASIO_MOVE_CAST(P)(p));       }     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -274,87 +305,88 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, thread_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, thread_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, thread_t>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, new_thread_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::static_query<T, thread_t>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, new_thread_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, new_thread_t>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, other_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::static_query<T, thread_t>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::static_query<T, new_thread_t>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, other_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, other_t>::value();   }    template <typename E, typename T = decltype(mapping_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = mapping_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const mapping_t& a, const mapping_t& b)   {     return a.value_ == b.value_;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const mapping_t& a, const mapping_t& b)   {     return a.value_ != b.value_;@@ -362,20 +394,22 @@    struct convertible_from_mapping_t   {-    constexpr convertible_from_mapping_t(mapping_t) {}+    ASIO_CONSTEXPR convertible_from_mapping_t(mapping_t) {}   };    template <typename Executor>-  friend constexpr mapping_t query(+  friend ASIO_CONSTEXPR mapping_t query(       const Executor& ex, convertible_from_mapping_t,-      enable_if_t<+      typename enable_if<         can_query<const Executor&, thread_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&, mapping_t<>::thread_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, mapping_t<>::thread_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, thread_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, thread_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -383,20 +417,21 @@   }    template <typename Executor>-  friend constexpr mapping_t query(+  friend ASIO_CONSTEXPR mapping_t query(       const Executor& ex, convertible_from_mapping_t,-      enable_if_t<+      typename enable_if<         !can_query<const Executor&, thread_t>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_query<const Executor&, new_thread_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(-      is_nothrow_query<const Executor&, mapping_t<>::new_thread_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, mapping_t<>::new_thread_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, new_thread_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, new_thread_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -404,22 +439,24 @@   }    template <typename Executor>-  friend constexpr mapping_t query(+  friend ASIO_CONSTEXPR mapping_t query(       const Executor& ex, convertible_from_mapping_t,-      enable_if_t<+      typename enable_if<         !can_query<const Executor&, thread_t>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !can_query<const Executor&, new_thread_t>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_query<const Executor&, other_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&, mapping_t<>::other_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, mapping_t<>::other_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, other_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, other_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -430,6 +467,10 @@   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(new_thread_t, new_thread);   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(other_t, other); +#if !defined(ASIO_HAS_CONSTEXPR)+  static const mapping_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private:   int value_; };@@ -441,7 +482,12 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>+const mapping_t<I> mapping_t<I>::instance;+#endif++template <int I> const typename mapping_t<I>::thread_t mapping_t<I>::thread;  template <int I>@@ -456,15 +502,35 @@ struct thread_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef mapping_t<I> polymorphic_query_result_type; -  constexpr thread_t()+  ASIO_CONSTEXPR thread_t()   {   } @@ -481,75 +547,58 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr thread_t static_query(-      enable_if_t<+  static ASIO_CONSTEXPR thread_t static_query(+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::query_free<T, thread_t>::is_valid-      >* = 0,-      enable_if_t<-        !can_query<T, new_thread_t<I>>::value-      >* = 0,-      enable_if_t<-        !can_query<T, other_t<I>>::value-      >* = 0) noexcept+      >::type* = 0,+      typename enable_if<+        !can_query<T, new_thread_t<I> >::value+      >::type* = 0,+      typename enable_if<+        !can_query<T, other_t<I> >::value+      >::type* = 0) ASIO_NOEXCEPT   {     return thread_t();   }    template <typename E, typename T = decltype(thread_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = thread_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr mapping_t<I> value()+  static ASIO_CONSTEXPR mapping_t<I> value()   {     return thread_t();   } -  friend constexpr bool operator==(const thread_t&, const thread_t&)-  {-    return true;-  }--  friend constexpr bool operator!=(const thread_t&, const thread_t&)-  {-    return false;-  }--  friend constexpr bool operator==(const thread_t&, const new_thread_t<I>&)-  {-    return false;-  }--  friend constexpr bool operator!=(const thread_t&, const new_thread_t<I>&)+  friend ASIO_CONSTEXPR bool operator==(+      const thread_t&, const thread_t&)   {     return true;   } -  friend constexpr bool operator==(const thread_t&, const other_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const thread_t&, const thread_t&)   {     return false;   }--  friend constexpr bool operator!=(const thread_t&, const other_t<I>&)-  {-    return true;-  } };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -563,15 +612,35 @@ struct new_thread_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef mapping_t<I> polymorphic_query_result_type; -  constexpr new_thread_t()+  ASIO_CONSTEXPR new_thread_t()   {   } @@ -588,52 +657,37 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(new_thread_t::static_query<E>())>-  static constexpr const T static_query_v = new_thread_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = new_thread_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr mapping_t<I> value()+  static ASIO_CONSTEXPR mapping_t<I> value()   {     return new_thread_t();   } -  friend constexpr bool operator==(const new_thread_t&, const new_thread_t&)-  {-    return true;-  }--  friend constexpr bool operator!=(const new_thread_t&, const new_thread_t&)-  {-    return false;-  }--  friend constexpr bool operator==(const new_thread_t&, const thread_t<I>&)-  {-    return false;-  }--  friend constexpr bool operator!=(const new_thread_t&, const thread_t<I>&)+  friend ASIO_CONSTEXPR bool operator==(+      const new_thread_t&, const new_thread_t&)   {     return true;   } -  friend constexpr bool operator==(const new_thread_t&, const other_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const new_thread_t&, const new_thread_t&)   {     return false;   }--  friend constexpr bool operator!=(const new_thread_t&, const other_t<I>&)-  {-    return true;-  } };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -647,15 +701,35 @@ struct other_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef mapping_t<I> polymorphic_query_result_type; -  constexpr other_t()+  ASIO_CONSTEXPR other_t()   {   } @@ -672,53 +746,37 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(other_t::static_query<E>())>-  static constexpr const T static_query_v = other_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = other_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr mapping_t<I> value()+  static ASIO_CONSTEXPR mapping_t<I> value()   {     return other_t();   } -  friend constexpr bool operator==(const other_t&, const other_t&)-  {-    return true;-  }--  friend constexpr bool operator!=(const other_t&, const other_t&)-  {-    return false;-  }--  friend constexpr bool operator==(const other_t&, const thread_t<I>&)-  {-    return false;-  }--  friend constexpr bool operator!=(const other_t&, const thread_t<I>&)+  friend ASIO_CONSTEXPR bool operator==(+      const other_t&, const other_t&)   {     return true;   } -  friend constexpr bool operator==(const other_t&, const new_thread_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const other_t&, const other_t&)   {     return false;   }--  friend constexpr bool operator!=(const other_t&, const new_thread_t<I>&)-  {-    return true;-  } };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -733,7 +791,11 @@  typedef detail::mapping_t<> mapping_t; -ASIO_INLINE_VARIABLE constexpr mapping_t mapping;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr mapping_t mapping;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const mapping_t& mapping = mapping_t::instance; }+#endif  } // namespace execution @@ -741,25 +803,81 @@  template <typename T> struct is_applicable_property<T, execution::mapping_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::mapping_t::thread_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::mapping_t::new_thread_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::mapping_t::other_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { }; @@ -771,42 +889,42 @@  template <typename T> struct query_free_default<T, execution::mapping_t,-  enable_if_t<+  typename enable_if<     can_query<T, execution::mapping_t::thread_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::mapping_t::thread_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::mapping_t::thread_t>::value));    typedef execution::mapping_t result_type; };  template <typename T> struct query_free_default<T, execution::mapping_t,-  enable_if_t<+  typename enable_if<     !can_query<T, execution::mapping_t::thread_t>::value       && can_query<T, execution::mapping_t::new_thread_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::mapping_t::new_thread_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::mapping_t::new_thread_t>::value));    typedef execution::mapping_t result_type; };  template <typename T> struct query_free_default<T, execution::mapping_t,-  enable_if_t<+  typename enable_if<     !can_query<T, execution::mapping_t::thread_t>::value       && !can_query<T, execution::mapping_t::new_thread_t>::value       && can_query<T, execution::mapping_t::other_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::mapping_t::other_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::mapping_t::other_t>::value));    typedef execution::mapping_t result_type; };@@ -818,18 +936,18 @@  template <typename T> struct static_query<T, execution::mapping_t,-  enable_if_t<+  typename enable_if<     execution::detail::mapping_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::mapping_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::mapping_t<0>::       query_static_constexpr_member<T>::value();@@ -838,21 +956,21 @@  template <typename T> struct static_query<T, execution::mapping_t,-  enable_if_t<+  typename enable_if<     !execution::detail::mapping_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::mapping_t<0>::         query_member<T>::is_valid       && traits::static_query<T, execution::mapping_t::thread_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::mapping_t::thread_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T, execution::mapping_t::thread_t>::value();   }@@ -860,22 +978,22 @@  template <typename T> struct static_query<T, execution::mapping_t,-  enable_if_t<+  typename enable_if<     !execution::detail::mapping_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::mapping_t<0>::         query_member<T>::is_valid       && !traits::static_query<T, execution::mapping_t::thread_t>::is_valid       && traits::static_query<T, execution::mapping_t::new_thread_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::mapping_t::new_thread_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T, execution::mapping_t::new_thread_t>::value();   }@@ -883,7 +1001,7 @@  template <typename T> struct static_query<T, execution::mapping_t,-  enable_if_t<+  typename enable_if<     !execution::detail::mapping_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::mapping_t<0>::@@ -891,15 +1009,15 @@       && !traits::static_query<T, execution::mapping_t::thread_t>::is_valid       && !traits::static_query<T, execution::mapping_t::new_thread_t>::is_valid       && traits::static_query<T, execution::mapping_t::other_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::mapping_t::other_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T, execution::mapping_t::other_t>::value();   }@@ -907,18 +1025,18 @@  template <typename T> struct static_query<T, execution::mapping_t::thread_t,-  enable_if_t<+  typename enable_if<     execution::detail::mapping::thread_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::mapping::thread_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::mapping::thread_t<0>::       query_static_constexpr_member<T>::value();@@ -927,7 +1045,7 @@  template <typename T> struct static_query<T, execution::mapping_t::thread_t,-  enable_if_t<+  typename enable_if<     !execution::detail::mapping::thread_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::mapping::thread_t<0>::@@ -935,14 +1053,14 @@       && !traits::query_free<T, execution::mapping_t::thread_t>::is_valid       && !can_query<T, execution::mapping_t::new_thread_t>::value       && !can_query<T, execution::mapping_t::other_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef execution::mapping_t::thread_t result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return result_type();   }@@ -950,18 +1068,18 @@  template <typename T> struct static_query<T, execution::mapping_t::new_thread_t,-  enable_if_t<+  typename enable_if<     execution::detail::mapping::new_thread_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::mapping::new_thread_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::mapping::new_thread_t<0>::       query_static_constexpr_member<T>::value();@@ -970,18 +1088,18 @@  template <typename T> struct static_query<T, execution::mapping_t::other_t,-  enable_if_t<+  typename enable_if<     execution::detail::mapping::other_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::mapping::other_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::mapping::other_t<0>::       query_static_constexpr_member<T>::value();@@ -990,6 +1108,46 @@  #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::mapping_t::thread_t,+  typename enable_if<+    static_query<T, execution::mapping_t::thread_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::mapping_t::thread_t>::result_type,+        execution::mapping_t::thread_t>::value));+};++template <typename T>+struct static_require<T, execution::mapping_t::new_thread_t,+  typename enable_if<+    static_query<T, execution::mapping_t::new_thread_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::mapping_t::new_thread_t>::result_type,+        execution::mapping_t::new_thread_t>::value));+};++template <typename T>+struct static_require<T, execution::mapping_t::other_t,+  typename enable_if<+    static_query<T, execution::mapping_t::other_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::mapping_t::other_t>::result_type,+        execution::mapping_t::other_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)  } // namespace traits 
link/modules/asio-standalone/asio/include/asio/execution/occupancy.hpp view
@@ -2,7 +2,7 @@ // execution/occupancy.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/traits/query_static_constexpr_member.hpp" #include "asio/traits/static_query.hpp"@@ -34,9 +36,10 @@ /// should occupy the associated execution context. struct occupancy_t {-  /// The occupancy_t property applies to executors.+  /// The occupancy_t property applies to executors, senders, and schedulers.   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor_v<T>;+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;    /// The occupancy_t property cannot be required.   static constexpr bool is_requirable = false;@@ -62,15 +65,35 @@ struct occupancy_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = false;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);   typedef std::size_t polymorphic_query_result_type; -  constexpr occupancy_t()+  ASIO_CONSTEXPR occupancy_t()   {   } @@ -81,17 +104,17 @@     struct type     {       template <typename P>-      static constexpr auto query(P&& p)+      static constexpr auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            conditional_t<true, T, P>::query(static_cast<P&&>(p))+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          conditional_t<true, T, P>::query(static_cast<P&&>(p))+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))         )       {-        return T::query(static_cast<P&&>(p));+        return T::query(ASIO_MOVE_CAST(P)(p));       }     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -107,17 +130,24 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(occupancy_t::static_query<E>())>-  static constexpr const T static_query_v = occupancy_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = occupancy_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_CONSTEXPR)+  static const occupancy_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR) };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -127,11 +157,20 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR)+template <int I>+const occupancy_t<I> occupancy_t<I>::instance;+#endif+ } // namespace detail  typedef detail::occupancy_t<> occupancy_t; -ASIO_INLINE_VARIABLE constexpr occupancy_t occupancy;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr occupancy_t occupancy;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const occupancy_t& occupancy = occupancy_t::instance; }+#endif  } // namespace execution @@ -139,7 +178,21 @@  template <typename T> struct is_applicable_property<T, execution::occupancy_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { }; @@ -152,18 +205,18 @@  template <typename T> struct static_query<T, execution::occupancy_t,-  enable_if_t<+  typename enable_if<     execution::detail::occupancy_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::occupancy_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::occupancy_t<0>::       query_static_constexpr_member<T>::value();
+ link/modules/asio-standalone/asio/include/asio/execution/operation_state.hpp view
@@ -0,0 +1,99 @@+//+// execution/operation_state.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_OPERATION_STATE_HPP+#define ASIO_EXECUTION_OPERATION_STATE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/start.hpp"++#if defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT) \+  && defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)+# define ASIO_HAS_DEDUCED_EXECUTION_IS_OPERATION_STATE_TRAIT 1+#endif // defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT)+       //   && defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename T>+struct is_operation_state_base :+  integral_constant<bool,+    is_destructible<T>::value+      && is_object<T>::value+  >+{+};++} // namespace detail++/// The is_operation_state trait detects whether a type T satisfies the+/// execution::operation_state concept.+/**+ * Class template @c is_operation_state is a type trait that is derived from+ * @c true_type if the type @c T meets the concept definition for an+ * @c operation_state, otherwise @c false_type.+ */+template <typename T>+struct is_operation_state :+#if defined(GENERATING_DOCUMENTATION)+  integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  conditional<+    can_start<typename add_lvalue_reference<T>::type>::value+      && is_nothrow_start<typename add_lvalue_reference<T>::type>::value,+    detail::is_operation_state_base<T>,+    false_type+  >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+ASIO_CONSTEXPR const bool is_operation_state_v =+  is_operation_state<T>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T>+ASIO_CONCEPT operation_state = is_operation_state<T>::value;++#define ASIO_EXECUTION_OPERATION_STATE \+  ::asio::execution::operation_state++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_OPERATION_STATE typename++#endif // defined(ASIO_HAS_CONCEPTS)++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_OPERATION_STATE_HPP
link/modules/asio-standalone/asio/include/asio/execution/outstanding_work.hpp view
@@ -2,7 +2,7 @@ // execution/outstanding_work.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/query.hpp" #include "asio/traits/query_free.hpp"@@ -37,9 +39,11 @@ /// A property to describe whether task submission is likely in the future. struct outstanding_work_t {-  /// The outstanding_work_t property applies to executors.+  /// The outstanding_work_t property applies to executors, senders, and+  /// schedulers.   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor_v<T>;+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;    /// The top-level outstanding_work_t property cannot be required.   static constexpr bool is_requirable = false;@@ -54,9 +58,11 @@   /// future submission of a function object.   struct untracked_t   {-    /// The outstanding_work_t::untracked_t property applies to executors.+    /// The outstanding_work_t::untracked_t property applies to executors,+    /// senders, and schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The outstanding_work_t::untracked_t property can be required.     static constexpr bool is_requirable = true;@@ -81,9 +87,11 @@   /// future submission of a function object.   struct tracked_t   {-    /// The outstanding_work_t::untracked_t property applies to executors.+    /// The outstanding_work_t::untracked_t property applies to executors,+    /// senders, and schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The outstanding_work_t::tracked_t property can be required.     static constexpr bool is_requirable = true;@@ -150,28 +158,48 @@ struct outstanding_work_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = false;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);   typedef outstanding_work_t polymorphic_query_result_type;    typedef detail::outstanding_work::untracked_t<I> untracked_t;   typedef detail::outstanding_work::tracked_t<I> tracked_t; -  constexpr outstanding_work_t()+  ASIO_CONSTEXPR outstanding_work_t()     : value_(-1)   {   } -  constexpr outstanding_work_t(untracked_t)+  ASIO_CONSTEXPR outstanding_work_t(untracked_t)     : value_(0)   {   } -  constexpr outstanding_work_t(tracked_t)+  ASIO_CONSTEXPR outstanding_work_t(tracked_t)     : value_(1)   {   }@@ -183,14 +211,16 @@     struct type     {       template <typename P>-      auto query(P&& p) const+      auto query(ASIO_MOVE_ARG(P) p) const         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().query(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().query(+            ASIO_MOVE_CAST(P)(p))         );     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -205,17 +235,17 @@     struct type     {       template <typename P>-      static constexpr auto query(P&& p)+      static constexpr auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            conditional_t<true, T, P>::query(static_cast<P&&>(p))+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          conditional_t<true, T, P>::query(static_cast<P&&>(p))+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))         )       {-        return T::query(static_cast<P&&>(p));+        return T::query(ASIO_MOVE_CAST(P)(p));       }     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -235,65 +265,66 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, untracked_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, untracked_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, untracked_t>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, tracked_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::static_query<T, untracked_t>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, tracked_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, tracked_t>::value();   }    template <typename E,       typename T = decltype(outstanding_work_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = outstanding_work_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const outstanding_work_t& a, const outstanding_work_t& b)   {     return a.value_ == b.value_;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const outstanding_work_t& a, const outstanding_work_t& b)   {     return a.value_ != b.value_;@@ -301,23 +332,25 @@    struct convertible_from_outstanding_work_t   {-    constexpr convertible_from_outstanding_work_t(outstanding_work_t)+    ASIO_CONSTEXPR convertible_from_outstanding_work_t(outstanding_work_t)     {     }   };    template <typename Executor>-  friend constexpr outstanding_work_t query(+  friend ASIO_CONSTEXPR outstanding_work_t query(       const Executor& ex, convertible_from_outstanding_work_t,-      enable_if_t<+      typename enable_if<         can_query<const Executor&, untracked_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&,-        outstanding_work_t<>::untracked_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&,+        outstanding_work_t<>::untracked_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, untracked_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, untracked_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -325,20 +358,22 @@   }    template <typename Executor>-  friend constexpr outstanding_work_t query(+  friend ASIO_CONSTEXPR outstanding_work_t query(       const Executor& ex, convertible_from_outstanding_work_t,-      enable_if_t<+      typename enable_if<         !can_query<const Executor&, untracked_t>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_query<const Executor&, tracked_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&,-        outstanding_work_t<>::tracked_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&,+        outstanding_work_t<>::tracked_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, tracked_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, tracked_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -348,6 +383,10 @@   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(untracked_t, untracked);   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(tracked_t, tracked); +#if !defined(ASIO_HAS_CONSTEXPR)+  static const outstanding_work_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private:   int value_; };@@ -359,7 +398,12 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>+const outstanding_work_t<I> outstanding_work_t<I>::instance;+#endif++template <int I> const typename outstanding_work_t<I>::untracked_t outstanding_work_t<I>::untracked; @@ -373,15 +417,35 @@ struct untracked_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef outstanding_work_t<I> polymorphic_query_result_type; -  constexpr untracked_t()+  ASIO_CONSTEXPR untracked_t()   {   } @@ -399,61 +463,55 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr untracked_t static_query(-      enable_if_t<+  static ASIO_CONSTEXPR untracked_t static_query(+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::query_free<T, untracked_t>::is_valid-      >* = 0,-      enable_if_t<-        !can_query<T, tracked_t<I>>::value-      >* = 0) noexcept+      >::type* = 0,+      typename enable_if<+        !can_query<T, tracked_t<I> >::value+      >::type* = 0) ASIO_NOEXCEPT   {     return untracked_t();   }    template <typename E, typename T = decltype(untracked_t::static_query<E>())>-  static constexpr const T static_query_v = untracked_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = untracked_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr outstanding_work_t<I> value()+  static ASIO_CONSTEXPR outstanding_work_t<I> value()   {     return untracked_t();   } -  friend constexpr bool operator==(const untracked_t&, const untracked_t&)+  friend ASIO_CONSTEXPR bool operator==(+      const untracked_t&, const untracked_t&)   {     return true;   } -  friend constexpr bool operator!=(const untracked_t&, const untracked_t&)-  {-    return false;-  }--  friend constexpr bool operator==(const untracked_t&, const tracked_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const untracked_t&, const untracked_t&)   {     return false;   }--  friend constexpr bool operator!=(const untracked_t&, const tracked_t<I>&)-  {-    return true;-  } };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -467,15 +525,35 @@ struct tracked_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef outstanding_work_t<I> polymorphic_query_result_type; -  constexpr tracked_t()+  ASIO_CONSTEXPR tracked_t()   {   } @@ -493,43 +571,37 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E, typename T = decltype(tracked_t::static_query<E>())>-  static constexpr const T static_query_v = tracked_t::static_query<E>();+  static ASIO_CONSTEXPR const T static_query_v+    = tracked_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr outstanding_work_t<I> value()+  static ASIO_CONSTEXPR outstanding_work_t<I> value()   {     return tracked_t();   } -  friend constexpr bool operator==(const tracked_t&, const tracked_t&)+  friend ASIO_CONSTEXPR bool operator==(+      const tracked_t&, const tracked_t&)   {     return true;   } -  friend constexpr bool operator!=(const tracked_t&, const tracked_t&)-  {-    return false;-  }--  friend constexpr bool operator==(const tracked_t&, const untracked_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const tracked_t&, const tracked_t&)   {     return false;   }--  friend constexpr bool operator!=(const tracked_t&, const untracked_t<I>&)-  {-    return true;-  } };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -544,7 +616,12 @@  typedef detail::outstanding_work_t<> outstanding_work_t; -ASIO_INLINE_VARIABLE constexpr outstanding_work_t outstanding_work;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr outstanding_work_t outstanding_work;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const outstanding_work_t&+  outstanding_work = outstanding_work_t::instance; }+#endif  } // namespace execution @@ -552,19 +629,61 @@  template <typename T> struct is_applicable_property<T, execution::outstanding_work_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::outstanding_work_t::untracked_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::outstanding_work_t::tracked_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { }; @@ -576,27 +695,27 @@  template <typename T> struct query_free_default<T, execution::outstanding_work_t,-  enable_if_t<+  typename enable_if<     can_query<T, execution::outstanding_work_t::untracked_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::outstanding_work_t::untracked_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::outstanding_work_t::untracked_t>::value));    typedef execution::outstanding_work_t result_type; };  template <typename T> struct query_free_default<T, execution::outstanding_work_t,-  enable_if_t<+  typename enable_if<     !can_query<T, execution::outstanding_work_t::untracked_t>::value       && can_query<T, execution::outstanding_work_t::tracked_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::outstanding_work_t::tracked_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::outstanding_work_t::tracked_t>::value));    typedef execution::outstanding_work_t result_type; };@@ -608,18 +727,18 @@  template <typename T> struct static_query<T, execution::outstanding_work_t,-  enable_if_t<+  typename enable_if<     execution::detail::outstanding_work_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::outstanding_work_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::outstanding_work_t<0>::       query_static_constexpr_member<T>::value();@@ -628,22 +747,22 @@  template <typename T> struct static_query<T, execution::outstanding_work_t,-  enable_if_t<+  typename enable_if<     !execution::detail::outstanding_work_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::outstanding_work_t<0>::         query_member<T>::is_valid       && traits::static_query<T,         execution::outstanding_work_t::untracked_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::outstanding_work_t::untracked_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T,         execution::outstanding_work_t::untracked_t>::value();@@ -652,7 +771,7 @@  template <typename T> struct static_query<T, execution::outstanding_work_t,-  enable_if_t<+  typename enable_if<     !execution::detail::outstanding_work_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::outstanding_work_t<0>::@@ -661,15 +780,15 @@         execution::outstanding_work_t::untracked_t>::is_valid       && traits::static_query<T,         execution::outstanding_work_t::tracked_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::outstanding_work_t::tracked_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T,         execution::outstanding_work_t::tracked_t>::value();@@ -678,18 +797,18 @@  template <typename T> struct static_query<T, execution::outstanding_work_t::untracked_t,-  enable_if_t<+  typename enable_if<     execution::detail::outstanding_work::untracked_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::outstanding_work::untracked_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::outstanding_work::untracked_t<0>::       query_static_constexpr_member<T>::value();@@ -698,7 +817,7 @@  template <typename T> struct static_query<T, execution::outstanding_work_t::untracked_t,-  enable_if_t<+  typename enable_if<     !execution::detail::outstanding_work::untracked_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::outstanding_work::untracked_t<0>::@@ -706,14 +825,14 @@       && !traits::query_free<T,         execution::outstanding_work_t::untracked_t>::is_valid       && !can_query<T, execution::outstanding_work_t::tracked_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef execution::outstanding_work_t::untracked_t result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return result_type();   }@@ -721,18 +840,18 @@  template <typename T> struct static_query<T, execution::outstanding_work_t::tracked_t,-  enable_if_t<+  typename enable_if<     execution::detail::outstanding_work::tracked_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::outstanding_work::tracked_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::outstanding_work::tracked_t<0>::       query_static_constexpr_member<T>::value();@@ -741,6 +860,34 @@  #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::outstanding_work_t::untracked_t,+  typename enable_if<+    static_query<T, execution::outstanding_work_t::untracked_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::outstanding_work_t::untracked_t>::result_type,+        execution::outstanding_work_t::untracked_t>::value));+};++template <typename T>+struct static_require<T, execution::outstanding_work_t::tracked_t,+  typename enable_if<+    static_query<T, execution::outstanding_work_t::tracked_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::outstanding_work_t::tracked_t>::result_type,+        execution::outstanding_work_t::tracked_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)  } // namespace traits 
link/modules/asio-standalone/asio/include/asio/execution/prefer_only.hpp view
@@ -2,7 +2,7 @@ // execution/prefer_only.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -65,17 +65,16 @@ template <typename InnerProperty, typename = void> struct prefer_only_is_preferable {-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false); };  template <typename InnerProperty> struct prefer_only_is_preferable<InnerProperty,-    enable_if_t<+    typename enable_if<       InnerProperty::is_preferable-    >-  >+    >::type> {-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true); };  template <typename InnerProperty, typename = void>@@ -85,10 +84,9 @@  template <typename InnerProperty> struct prefer_only_polymorphic_query_result_type<InnerProperty,-    void_t<+    typename void_type<       typename InnerProperty::polymorphic_query_result_type-    >-  >+    >::type> {   typedef typename InnerProperty::polymorphic_query_result_type     polymorphic_query_result_type;@@ -105,14 +103,14 @@   } }; -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  template <typename InnerProperty> struct prefer_only_property<InnerProperty,-    void_t<+    typename void_type<       decltype(asio::declval<const InnerProperty>().value())-    >-  >+    >::type> {   InnerProperty property; @@ -121,15 +119,17 @@   {   } -  constexpr auto value() const-    noexcept(noexcept(asio::declval<const InnerProperty>().value()))+  ASIO_CONSTEXPR auto value() const+    ASIO_NOEXCEPT_IF((+      noexcept(asio::declval<const InnerProperty>().value())))     -> decltype(asio::declval<const InnerProperty>().value())   {     return property.value();   } }; -#else // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#else // defined(ASIO_HAS_DECLTYPE)+      //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  struct prefer_only_memfns_base {@@ -158,12 +158,11 @@  template <typename InnerProperty> struct prefer_only_property<InnerProperty,-    enable_if_t<+    typename enable_if<       sizeof(prefer_only_value_memfn_helper<InnerProperty>(0)) != 1         && !is_same<typename InnerProperty::polymorphic_query_result_type,           void>::value-    >-  >+    >::type> {   InnerProperty property; @@ -172,14 +171,15 @@   {   } -  constexpr typename InnerProperty::polymorphic_query_result_type+  ASIO_CONSTEXPR typename InnerProperty::polymorphic_query_result_type   value() const   {     return property.value();   } }; -#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  } // namespace detail @@ -189,9 +189,9 @@   detail::prefer_only_polymorphic_query_result_type<InnerProperty>,   detail::prefer_only_property<InnerProperty> {-  static constexpr bool is_requirable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false); -  constexpr prefer_only(const InnerProperty& p)+  ASIO_CONSTEXPR prefer_only(const InnerProperty& p)     : detail::prefer_only_property<InnerProperty>(p)   {   }@@ -199,33 +199,35 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, InnerProperty>::result_type   static_query()-    noexcept(traits::static_query<T, InnerProperty>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      traits::static_query<T, InnerProperty>::is_noexcept))   {     return traits::static_query<T, InnerProperty>::value();   }    template <typename E, typename T = decltype(prefer_only::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = prefer_only::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)    template <typename Executor, typename Property>-  friend constexpr-  prefer_result_t<const Executor&, const InnerProperty&>+  friend ASIO_CONSTEXPR+  typename prefer_result<const Executor&, const InnerProperty&>::type   prefer(const Executor& ex, const prefer_only<Property>& p,-      enable_if_t<+      typename enable_if<         is_same<Property, InnerProperty>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_prefer<const Executor&, const InnerProperty&>::value-      >* = 0)+      >::type* = 0) #if !defined(ASIO_MSVC) \   && !defined(__clang__) // Clang crashes if noexcept is used here.-    noexcept(is_nothrow_prefer<const Executor&, const InnerProperty&>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_prefer<const Executor&, const InnerProperty&>::value)) #endif // !defined(ASIO_MSVC)        //   && !defined(__clang__)   {@@ -233,18 +235,19 @@   }    template <typename Executor, typename Property>-  friend constexpr-  query_result_t<const Executor&, const InnerProperty&>+  friend ASIO_CONSTEXPR+  typename query_result<const Executor&, const InnerProperty&>::type   query(const Executor& ex, const prefer_only<Property>& p,-      enable_if_t<+      typename enable_if<         is_same<Property, InnerProperty>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_query<const Executor&, const InnerProperty&>::value-      >* = 0)+      >::type* = 0) #if !defined(ASIO_MSVC) \   && !defined(__clang__) // Clang crashes if noexcept is used here.-    noexcept(is_nothrow_query<const Executor&, const InnerProperty&>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, const InnerProperty&>::value)) #endif // !defined(ASIO_MSVC)        //   && !defined(__clang__)   {@@ -262,7 +265,7 @@ } // namespace execution  template <typename T, typename InnerProperty>-struct is_applicable_property<T, execution::prefer_only<InnerProperty>>+struct is_applicable_property<T, execution::prefer_only<InnerProperty> >   : is_applicable_property<T, InnerProperty> { };@@ -273,7 +276,7 @@   || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)  template <typename T, typename InnerProperty>-struct static_query<T, execution::prefer_only<InnerProperty>> :+struct static_query<T, execution::prefer_only<InnerProperty> > :   static_query<T, const InnerProperty&> { };@@ -285,16 +288,16 @@  template <typename T, typename InnerProperty> struct prefer_free_default<T, execution::prefer_only<InnerProperty>,-    enable_if_t<+    typename enable_if<       can_prefer<const T&, const InnerProperty&>::value-    >-  >+    >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_prefer<const T&, const InnerProperty&>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_prefer<const T&, const InnerProperty&>::value)); -  typedef prefer_result_t<const T&, const InnerProperty&> result_type;+  typedef typename prefer_result<const T&,+      const InnerProperty&>::type result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)@@ -303,16 +306,16 @@  template <typename T, typename InnerProperty> struct query_free<T, execution::prefer_only<InnerProperty>,-    enable_if_t<+    typename enable_if<       can_query<const T&, const InnerProperty&>::value-    >-  >+    >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<const T&, const InnerProperty&>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<const T&, const InnerProperty&>::value)); -  typedef query_result_t<const T&, const InnerProperty&> result_type;+  typedef typename query_result<const T&,+      const InnerProperty&>::type result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)
+ link/modules/asio-standalone/asio/include/asio/execution/receiver.hpp view
@@ -0,0 +1,285 @@+//+// execution/receiver.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_RECEIVER_HPP+#define ASIO_EXECUTION_RECEIVER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"+#include "asio/execution/set_done.hpp"+#include "asio/execution/set_error.hpp"+#include "asio/execution/set_value.hpp"++#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+# include <exception>+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+# include "asio/error_code.hpp"+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)++#if defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT) \+  && defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT) \+  && defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT) \+  && defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT) \+  && defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT) \+  && defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT) \+  && defined(ASIO_HAS_DEDUCED_RECEIVER_OF_FREE_TRAIT) \+  && defined(ASIO_HAS_DEDUCED_RECEIVER_OF_MEMBER_TRAIT)+# define ASIO_HAS_DEDUCED_EXECUTION_IS_RECEIVER_TRAIT 1+#endif // defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)+       //   && defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)+       //   && defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)+       //   && defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)+       //   && defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)+       //   && defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)+       //   && defined(ASIO_HAS_DEDUCED_RECEIVER_OF_FREE_TRAIT)+       //   && defined(ASIO_HAS_DEDUCED_RECEIVER_OF_MEMBER_TRAIT)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename T, typename E>+struct is_receiver_base :+  integral_constant<bool,+    is_move_constructible<typename remove_cvref<T>::type>::value+      && is_constructible<typename remove_cvref<T>::type, T>::value+  >+{+};++} // namespace detail++#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+# define ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT = std::exception_ptr+#else // defined(ASIO_HAS_STD_EXCEPTION_PTR)+# define ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT \+  = ::asio::error_code+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)++/// The is_receiver trait detects whether a type T satisfies the+/// execution::receiver concept.+/**+ * Class template @c is_receiver is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a receiver for+ * error type @c E, otherwise @c false_type.+ */+template <typename T, typename E ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT>+struct is_receiver :+#if defined(GENERATING_DOCUMENTATION)+  integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  conditional<+    can_set_done<typename remove_cvref<T>::type>::value+      && is_nothrow_set_done<typename remove_cvref<T>::type>::value+      && can_set_error<typename remove_cvref<T>::type, E>::value+      && is_nothrow_set_error<typename remove_cvref<T>::type, E>::value,+    detail::is_receiver_base<T, E>,+    false_type+  >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename E ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT>+ASIO_CONSTEXPR const bool is_receiver_v = is_receiver<T, E>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T, typename E ASIO_EXECUTION_RECEIVER_ERROR_DEFAULT>+ASIO_CONCEPT receiver = is_receiver<T, E>::value;++#define ASIO_EXECUTION_RECEIVER ::asio::execution::receiver++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_RECEIVER typename++#endif // defined(ASIO_HAS_CONCEPTS)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)++/// The is_receiver_of trait detects whether a type T satisfies the+/// execution::receiver_of concept for some set of value arguments.+/**+ * Class template @c is_receiver_of is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a receiver for+ * value arguments @c Vs, otherwise @c false_type.+ */+template <typename T, typename... Vs>+struct is_receiver_of :+#if defined(GENERATING_DOCUMENTATION)+  integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  conditional<+    is_receiver<T>::value,+    can_set_value<typename remove_cvref<T>::type, Vs...>,+    false_type+  >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename... Vs>+ASIO_CONSTEXPR const bool is_receiver_of_v =+  is_receiver_of<T, Vs...>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T, typename... Vs>+ASIO_CONCEPT receiver_of = is_receiver_of<T, Vs...>::value;++#define ASIO_EXECUTION_RECEIVER_OF_0 \+  ::asio::execution::receiver_of++#define ASIO_EXECUTION_RECEIVER_OF_1(v) \+  ::asio::execution::receiver_of<v>++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_RECEIVER_OF_0 typename+#define ASIO_EXECUTION_RECEIVER_OF_1(v) typename++#endif // defined(ASIO_HAS_CONCEPTS)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+      //   || defined(GENERATING_DOCUMENTATION)++template <typename T, typename = void,+    typename = void, typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void, typename = void>+struct is_receiver_of;++template <typename T>+struct is_receiver_of<T> :+  conditional<+    is_receiver<T>::value,+    can_set_value<typename remove_cvref<T>::type>,+    false_type+  >::type+{+};++#define ASIO_PRIVATE_RECEIVER_OF_TRAITS_DEF(n) \+  template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+  struct is_receiver_of<T, ASIO_VARIADIC_TARGS(n)> : \+    conditional< \+      conditional<true, is_receiver<T>, void>::type::value, \+      can_set_value< \+        typename remove_cvref<T>::type, \+        ASIO_VARIADIC_TARGS(n)>, \+      false_type \+    >::type \+  { \+  }; \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_RECEIVER_OF_TRAITS_DEF)+#undef ASIO_PRIVATE_RECEIVER_OF_TRAITS_DEF++#define ASIO_EXECUTION_RECEIVER_OF_0 typename+#define ASIO_EXECUTION_RECEIVER_OF_1(v) typename++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)++/// The is_nothrow_receiver_of trait detects whether a type T satisfies the+/// execution::receiver_of concept for some set of value arguments, with a+/// noexcept @c set_value operation.+/**+ * Class template @c is_nothrow_receiver_of is a type trait that is derived+ * from @c true_type if the type @c T meets the concept definition for a+ * receiver for value arguments @c Vs, and the expression+ * <tt>execution::set_value(declval<T>(), declval<Ts>()...)</tt> is noexcept,+ * otherwise @c false_type.+ */+template <typename T, typename... Vs>+struct is_nothrow_receiver_of :+#if defined(GENERATING_DOCUMENTATION)+  integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  integral_constant<bool,+    is_receiver_of<T, Vs...>::value+      && is_nothrow_set_value<typename remove_cvref<T>::type, Vs...>::value+  >+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename... Vs>+ASIO_CONSTEXPR const bool is_nothrow_receiver_of_v =+  is_nothrow_receiver_of<T, Vs...>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+      //   || defined(GENERATING_DOCUMENTATION)++template <typename T, typename = void,+    typename = void, typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void, typename = void>+struct is_nothrow_receiver_of;++template <typename T>+struct is_nothrow_receiver_of<T> :+  integral_constant<bool,+    is_receiver_of<T>::value+      && is_nothrow_set_value<typename remove_cvref<T>::type>::value+  >+{+};++#define ASIO_PRIVATE_NOTHROW_RECEIVER_OF_TRAITS_DEF(n) \+  template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+  struct is_nothrow_receiver_of<T, ASIO_VARIADIC_TARGS(n)> : \+    integral_constant<bool, \+      is_receiver_of<T, ASIO_VARIADIC_TARGS(n)>::value \+        && is_nothrow_set_value<typename remove_cvref<T>::type, \+          ASIO_VARIADIC_TARGS(n)>::value \+    > \+  { \+  }; \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_NOTHROW_RECEIVER_OF_TRAITS_DEF)+#undef ASIO_PRIVATE_NOTHROW_RECEIVER_OF_TRAITS_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_RECEIVER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/receiver_invocation_error.hpp view
@@ -0,0 +1,48 @@+//+// execution/receiver_invocation_error.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_RECEIVER_INVOCATION_ERROR_HPP+#define ASIO_EXECUTION_RECEIVER_INVOCATION_ERROR_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <stdexcept>++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {++/// Exception reported via @c set_error when an exception escapes from+/// @c set_value.+class receiver_invocation_error+  : public std::runtime_error+#if defined(ASIO_HAS_STD_NESTED_EXCEPTION)+  , public std::nested_exception+#endif // defined(ASIO_HAS_STD_NESTED_EXCEPTION)+{+public:+  /// Constructor.+  ASIO_DECL receiver_invocation_error();+};++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#if defined(ASIO_HEADER_ONLY)+# include "asio/execution/impl/receiver_invocation_error.ipp"+#endif // defined(ASIO_HEADER_ONLY)++#endif // ASIO_EXECUTION_RECEIVER_INVOCATION_ERROR_HPP
link/modules/asio-standalone/asio/include/asio/execution/relationship.hpp view
@@ -2,7 +2,7 @@ // execution/relationship.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,8 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" #include "asio/execution/executor.hpp"+#include "asio/execution/scheduler.hpp"+#include "asio/execution/sender.hpp" #include "asio/is_applicable_property.hpp" #include "asio/query.hpp" #include "asio/traits/query_free.hpp"@@ -38,9 +40,10 @@ /// the calling context. struct relationship_t {-  /// The relationship_t property applies to executors.+  /// The relationship_t property applies to executors, senders, and schedulers.   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor_v<T>;+  static constexpr bool is_applicable_property_v =+    is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;    /// The top-level relationship_t property cannot be required.   static constexpr bool is_requirable = false;@@ -55,9 +58,11 @@   /// continuation of the calling context.   struct fork_t   {-    /// The relationship_t::fork_t property applies to executors.+    /// The relationship_t::fork_t property applies to executors, senders, and+    /// schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The relationship_t::fork_t property can be required.     static constexpr bool is_requirable = true;@@ -82,9 +87,11 @@   /// of the calling context.   struct continuation_t   {-    /// The relationship_t::continuation_t property applies to executors.+    /// The relationship_t::continuation_t property applies to executors,+    /// senders, and schedulers.     template <typename T>-    static constexpr bool is_applicable_property_v = is_executor_v<T>;+    static constexpr bool is_applicable_property_v =+      is_executor_v<T> || is_sender_v<T> || is_scheduler_v<T>;      /// The relationship_t::continuation_t property can be required.     static constexpr bool is_requirable = true;@@ -150,28 +157,48 @@ struct relationship_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = false;-  static constexpr bool is_preferable = false;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = false);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = false);   typedef relationship_t polymorphic_query_result_type;    typedef detail::relationship::fork_t<I> fork_t;   typedef detail::relationship::continuation_t<I> continuation_t; -  constexpr relationship_t()+  ASIO_CONSTEXPR relationship_t()     : value_(-1)   {   } -  constexpr relationship_t(fork_t)+  ASIO_CONSTEXPR relationship_t(fork_t)     : value_(0)   {   } -  constexpr relationship_t(continuation_t)+  ASIO_CONSTEXPR relationship_t(continuation_t)     : value_(1)   {   }@@ -183,14 +210,16 @@     struct type     {       template <typename P>-      auto query(P&& p) const+      auto query(ASIO_MOVE_ARG(P) p) const         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().query(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().query(+            ASIO_MOVE_CAST(P)(p))         );     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -205,17 +234,17 @@     struct type     {       template <typename P>-      static constexpr auto query(P&& p)+      static constexpr auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            conditional_t<true, T, P>::query(static_cast<P&&>(p))+            conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          conditional_t<true, T, P>::query(static_cast<P&&>(p))+          conditional<true, T, P>::type::query(ASIO_MOVE_CAST(P)(p))         )       {-        return T::query(static_cast<P&&>(p));+        return T::query(ASIO_MOVE_CAST(P)(p));       }     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT)@@ -235,65 +264,66 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, fork_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, fork_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, fork_t>::value();   }    template <typename T>-  static constexpr+  static ASIO_CONSTEXPR   typename traits::static_query<T, continuation_t>::result_type   static_query(-      enable_if_t<+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::static_query<T, fork_t>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         traits::static_query<T, continuation_t>::is_valid-      >* = 0) noexcept+      >::type* = 0) ASIO_NOEXCEPT   {     return traits::static_query<T, continuation_t>::value();   }    template <typename E,       typename T = decltype(relationship_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = relationship_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  friend constexpr bool operator==(+  friend ASIO_CONSTEXPR bool operator==(       const relationship_t& a, const relationship_t& b)   {     return a.value_ == b.value_;   } -  friend constexpr bool operator!=(+  friend ASIO_CONSTEXPR bool operator!=(       const relationship_t& a, const relationship_t& b)   {     return a.value_ != b.value_;@@ -301,22 +331,24 @@    struct convertible_from_relationship_t   {-    constexpr convertible_from_relationship_t(relationship_t)+    ASIO_CONSTEXPR convertible_from_relationship_t(relationship_t)     {     }   };    template <typename Executor>-  friend constexpr relationship_t query(+  friend ASIO_CONSTEXPR relationship_t query(       const Executor& ex, convertible_from_relationship_t,-      enable_if_t<+      typename enable_if<         can_query<const Executor&, fork_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&, relationship_t<>::fork_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, relationship_t<>::fork_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, fork_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, fork_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -324,20 +356,22 @@   }    template <typename Executor>-  friend constexpr relationship_t query(+  friend ASIO_CONSTEXPR relationship_t query(       const Executor& ex, convertible_from_relationship_t,-      enable_if_t<+      typename enable_if<         !can_query<const Executor&, fork_t>::value-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         can_query<const Executor&, continuation_t>::value-      >* = 0)+      >::type* = 0) #if !defined(__clang__) // Clang crashes if noexcept is used here. #if defined(ASIO_MSVC) // Visual C++ wants the type to be qualified.-    noexcept(is_nothrow_query<const Executor&,-        relationship_t<>::continuation_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&,+        relationship_t<>::continuation_t>::value)) #else // defined(ASIO_MSVC)-    noexcept(is_nothrow_query<const Executor&, continuation_t>::value)+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, continuation_t>::value)) #endif // defined(ASIO_MSVC) #endif // !defined(__clang__)   {@@ -347,6 +381,10 @@   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(fork_t, fork);   ASIO_STATIC_CONSTEXPR_DEFAULT_INIT(continuation_t, continuation); +#if !defined(ASIO_HAS_CONSTEXPR)+  static const relationship_t instance;+#endif // !defined(ASIO_HAS_CONSTEXPR)+ private:   int value_; };@@ -358,10 +396,16 @@ #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) +#if !defined(ASIO_HAS_CONSTEXPR) template <int I>-const typename relationship_t<I>::fork_t relationship_t<I>::fork;+const relationship_t<I> relationship_t<I>::instance;+#endif  template <int I>+const typename relationship_t<I>::fork_t+relationship_t<I>::fork;++template <int I> const typename relationship_t<I>::continuation_t relationship_t<I>::continuation; @@ -371,15 +415,35 @@ struct fork_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef relationship_t<I> polymorphic_query_result_type; -  constexpr fork_t()+  ASIO_CONSTEXPR fork_t()   {   } @@ -396,61 +460,55 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename T>-  static constexpr fork_t static_query(-      enable_if_t<+  static ASIO_CONSTEXPR fork_t static_query(+      typename enable_if<         !query_static_constexpr_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !query_member<T>::is_valid-      >* = 0,-      enable_if_t<+      >::type* = 0,+      typename enable_if<         !traits::query_free<T, fork_t>::is_valid-      >* = 0,-      enable_if_t<-        !can_query<T, continuation_t<I>>::value-      >* = 0) noexcept+      >::type* = 0,+      typename enable_if<+        !can_query<T, continuation_t<I> >::value+      >::type* = 0) ASIO_NOEXCEPT   {     return fork_t();   }    template <typename E, typename T = decltype(fork_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = fork_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr relationship_t<I> value()+  static ASIO_CONSTEXPR relationship_t<I> value()   {     return fork_t();   } -  friend constexpr bool operator==(const fork_t&, const fork_t&)+  friend ASIO_CONSTEXPR bool operator==(+      const fork_t&, const fork_t&)   {     return true;   } -  friend constexpr bool operator!=(const fork_t&, const fork_t&)-  {-    return false;-  }--  friend constexpr bool operator==(const fork_t&, const continuation_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const fork_t&, const fork_t&)   {     return false;   }--  friend constexpr bool operator!=(const fork_t&, const continuation_t<I>&)-  {-    return true;-  } };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -464,15 +522,35 @@ struct continuation_t { #if defined(ASIO_HAS_VARIABLE_TEMPLATES)+# if defined(ASIO_NO_DEPRECATED)   template <typename T>-  static constexpr bool is_applicable_property_v = is_executor<T>::value;+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value));+# else // defined(ASIO_NO_DEPRECATED)+  template <typename T>+  ASIO_STATIC_CONSTEXPR(bool,+    is_applicable_property_v = (+      is_executor<T>::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_sender<T>+          >::type::value+        || conditional<+            is_executor<T>::value,+            false_type,+            is_scheduler<T>+          >::type::value+      ));+# endif // defined(ASIO_NO_DEPRECATED) #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) -  static constexpr bool is_requirable = true;-  static constexpr bool is_preferable = true;+  ASIO_STATIC_CONSTEXPR(bool, is_requirable = true);+  ASIO_STATIC_CONSTEXPR(bool, is_preferable = true);   typedef relationship_t<I> polymorphic_query_result_type; -  constexpr continuation_t()+  ASIO_CONSTEXPR continuation_t()   {   } @@ -490,44 +568,38 @@ #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)   template <typename T>-  static constexpr typename query_static_constexpr_member<T>::result_type+  static ASIO_CONSTEXPR+  typename query_static_constexpr_member<T>::result_type   static_query()-    noexcept(query_static_constexpr_member<T>::is_noexcept)+    ASIO_NOEXCEPT_IF((+      query_static_constexpr_member<T>::is_noexcept))   {     return query_static_constexpr_member<T>::value();   }    template <typename E,       typename T = decltype(continuation_t::static_query<E>())>-  static constexpr const T static_query_v+  static ASIO_CONSTEXPR const T static_query_v     = continuation_t::static_query<E>(); #endif // defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   && defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES) -  static constexpr relationship_t<I> value()+  static ASIO_CONSTEXPR relationship_t<I> value()   {     return continuation_t();   } -  friend constexpr bool operator==(const continuation_t&, const continuation_t&)+  friend ASIO_CONSTEXPR bool operator==(+      const continuation_t&, const continuation_t&)   {     return true;   } -  friend constexpr bool operator!=(const continuation_t&, const continuation_t&)-  {-    return false;-  }--  friend constexpr bool operator==(const continuation_t&, const fork_t<I>&)+  friend ASIO_CONSTEXPR bool operator!=(+      const continuation_t&, const continuation_t&)   {     return false;   }--  friend constexpr bool operator!=(const continuation_t&, const fork_t<I>&)-  {-    return true;-  } };  #if defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT) \@@ -542,7 +614,12 @@  typedef detail::relationship_t<> relationship_t; -ASIO_INLINE_VARIABLE constexpr relationship_t relationship;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr relationship_t relationship;+#else // defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+namespace { static const relationship_t&+  relationship = relationship_t::instance; }+#endif  } // namespace execution @@ -550,19 +627,61 @@  template <typename T> struct is_applicable_property<T, execution::relationship_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::relationship_t::fork_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { };  template <typename T> struct is_applicable_property<T, execution::relationship_t::continuation_t>-  : integral_constant<bool, execution::is_executor<T>::value>+  : integral_constant<bool,+      execution::is_executor<T>::value+#if !defined(ASIO_NO_DEPRECATED)+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_sender<T>+          >::type::value+        || conditional<+            execution::is_executor<T>::value,+            false_type,+            execution::is_scheduler<T>+          >::type::value+#endif // !defined(ASIO_NO_DEPRECATED)+    > { }; @@ -574,27 +693,27 @@  template <typename T> struct query_free_default<T, execution::relationship_t,-  enable_if_t<+  typename enable_if<     can_query<T, execution::relationship_t::fork_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::relationship_t::fork_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::relationship_t::fork_t>::value));    typedef execution::relationship_t result_type; };  template <typename T> struct query_free_default<T, execution::relationship_t,-  enable_if_t<+  typename enable_if<     !can_query<T, execution::relationship_t::fork_t>::value       && can_query<T, execution::relationship_t::continuation_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<T, execution::relationship_t::continuation_t>::value;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    (is_nothrow_query<T, execution::relationship_t::continuation_t>::value));    typedef execution::relationship_t result_type; };@@ -606,18 +725,18 @@  template <typename T> struct static_query<T, execution::relationship_t,-  enable_if_t<+  typename enable_if<     execution::detail::relationship_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::relationship_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::relationship_t<0>::       query_static_constexpr_member<T>::value();@@ -626,22 +745,22 @@  template <typename T> struct static_query<T, execution::relationship_t,-  enable_if_t<+  typename enable_if<     !execution::detail::relationship_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::relationship_t<0>::         query_member<T>::is_valid       && traits::static_query<T,         execution::relationship_t::fork_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::relationship_t::fork_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T,         execution::relationship_t::fork_t>::value();@@ -650,7 +769,7 @@  template <typename T> struct static_query<T, execution::relationship_t,-  enable_if_t<+  typename enable_if<     !execution::detail::relationship_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::relationship_t<0>::@@ -659,15 +778,15 @@         execution::relationship_t::fork_t>::is_valid       && traits::static_query<T,         execution::relationship_t::continuation_t>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename traits::static_query<T,     execution::relationship_t::continuation_t>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return traits::static_query<T,         execution::relationship_t::continuation_t>::value();@@ -676,18 +795,18 @@  template <typename T> struct static_query<T, execution::relationship_t::fork_t,-  enable_if_t<+  typename enable_if<     execution::detail::relationship::fork_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::relationship::fork_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::relationship::fork_t<0>::       query_static_constexpr_member<T>::value();@@ -696,7 +815,7 @@  template <typename T> struct static_query<T, execution::relationship_t::fork_t,-  enable_if_t<+  typename enable_if<     !execution::detail::relationship::fork_t<0>::         query_static_constexpr_member<T>::is_valid       && !execution::detail::relationship::fork_t<0>::@@ -704,14 +823,14 @@       && !traits::query_free<T,         execution::relationship_t::fork_t>::is_valid       && !can_query<T, execution::relationship_t::continuation_t>::value-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef execution::relationship_t::fork_t result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return result_type();   }@@ -719,18 +838,18 @@  template <typename T> struct static_query<T, execution::relationship_t::continuation_t,-  enable_if_t<+  typename enable_if<     execution::detail::relationship::continuation_t<0>::       query_static_constexpr_member<T>::is_valid-  >>+  >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);    typedef typename execution::detail::relationship::continuation_t<0>::     query_static_constexpr_member<T>::result_type result_type; -  static constexpr result_type value()+  static ASIO_CONSTEXPR result_type value()   {     return execution::detail::relationship::continuation_t<0>::       query_static_constexpr_member<T>::value();@@ -739,6 +858,34 @@  #endif // !defined(ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT)        //   || !defined(ASIO_HAS_SFINAE_VARIABLE_TEMPLATES)++#if !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)++template <typename T>+struct static_require<T, execution::relationship_t::fork_t,+  typename enable_if<+    static_query<T, execution::relationship_t::fork_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::relationship_t::fork_t>::result_type,+        execution::relationship_t::fork_t>::value));+};++template <typename T>+struct static_require<T, execution::relationship_t::continuation_t,+  typename enable_if<+    static_query<T, execution::relationship_t::continuation_t>::is_valid+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid =+    (is_same<typename static_query<T,+      execution::relationship_t::continuation_t>::result_type,+        execution::relationship_t::continuation_t>::value));+};++#endif // !defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)  } // namespace traits 
+ link/modules/asio-standalone/asio/include/asio/execution/schedule.hpp view
@@ -0,0 +1,292 @@+//+// execution/schedule.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_SCHEDULE_HPP+#define ASIO_EXECUTION_SCHEDULE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/executor.hpp"+#include "asio/traits/schedule_member.hpp"+#include "asio/traits/schedule_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that is used to obtain a sender from a scheduler.+/**+ * The name <tt>execution::schedule</tt> denotes a customisation point object.+ * For some subexpression <tt>s</tt>, let <tt>S</tt> be a type such that+ * <tt>decltype((s))</tt> is <tt>S</tt>. The expression+ * <tt>execution::schedule(s)</tt> is expression-equivalent to:+ *+ * @li <tt>s.schedule()</tt>, if that expression is valid and its type models+ *   <tt>sender</tt>.+ *+ * @li Otherwise, <tt>schedule(s)</tt>, if that expression is valid and its+ *   type models <tt>sender</tt> with overload resolution performed in a context+ *   that includes the declaration <tt>void schedule();</tt> and that does not+ *   include a declaration of <tt>execution::schedule</tt>.+ *+ * @li Otherwise, <tt>S</tt> if <tt>S</tt> satisfies <tt>executor</tt>.+ *+ * @li Otherwise, <tt>execution::schedule(s)</tt> is ill-formed.+ */+inline constexpr unspecified schedule = unspecified;++/// A type trait that determines whether a @c schedule expression is+/// well-formed.+/**+ * Class template @c can_schedule is a trait that is derived from @c true_type+ * if the expression <tt>execution::schedule(std::declval<S>())</tt> is well+ * formed; otherwise @c false_type.+ */+template <typename S>+struct can_schedule :+  integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_schedule_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::execution::is_executor;+using asio::traits::schedule_free;+using asio::traits::schedule_member;++void schedule();++enum overload_type+{+  identity,+  call_member,+  call_free,+  ill_formed+};++template <typename S, typename = void, typename = void, typename = void>+struct call_traits+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++template <typename S>+struct call_traits<S,+  typename enable_if<+    schedule_member<S>::is_valid+  >::type> :+  schedule_member<S>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename S>+struct call_traits<S,+  typename enable_if<+    !schedule_member<S>::is_valid+  >::type,+  typename enable_if<+    schedule_free<S>::is_valid+  >::type> :+  schedule_free<S>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename S>+struct call_traits<S,+  typename enable_if<+    !schedule_member<S>::is_valid+  >::type,+  typename enable_if<+    !schedule_free<S>::is_valid+  >::type,+  typename enable_if<+    is_executor<typename decay<S>::type>::value+  >::type>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);++#if defined(ASIO_HAS_MOVE)+  typedef ASIO_MOVE_ARG(S) result_type;+#else // defined(ASIO_HAS_MOVE)+  typedef ASIO_MOVE_ARG(typename decay<S>::type) result_type;+#endif // defined(ASIO_HAS_MOVE)+};++struct impl+{+  template <typename S>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S>::overload == identity,+    typename call_traits<S>::result_type+  >::type+  operator()(ASIO_MOVE_ARG(S) s) const+    ASIO_NOEXCEPT_IF((+      call_traits<S>::is_noexcept))+  {+    return ASIO_MOVE_CAST(S)(s);+  }++#if defined(ASIO_HAS_MOVE)+  template <typename S>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S>::overload == call_member,+    typename call_traits<S>::result_type+  >::type+  operator()(S&& s) const+    ASIO_NOEXCEPT_IF((+      call_traits<S>::is_noexcept))+  {+    return ASIO_MOVE_CAST(S)(s).schedule();+  }++  template <typename S>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S>::overload == call_free,+    typename call_traits<S>::result_type+  >::type+  operator()(S&& s) const+    ASIO_NOEXCEPT_IF((+      call_traits<S>::is_noexcept))+  {+    return schedule(ASIO_MOVE_CAST(S)(s));+  }+#else // defined(ASIO_HAS_MOVE)+  template <typename S>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&>::overload == call_member,+    typename call_traits<S&>::result_type+  >::type+  operator()(S& s) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&>::is_noexcept))+  {+    return s.schedule();+  }++  template <typename S>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&>::overload == call_member,+    typename call_traits<const S&>::result_type+  >::type+  operator()(const S& s) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&>::is_noexcept))+  {+    return s.schedule();+  }++  template <typename S>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&>::overload == call_free,+    typename call_traits<S&>::result_type+  >::type+  operator()(S& s) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&>::is_noexcept))+  {+    return schedule(s);+  }++  template <typename S>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&>::overload == call_free,+    typename call_traits<const S&>::result_type+  >::type+  operator()(const S& s) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&>::is_noexcept))+  {+    return schedule(s);+  }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+  static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_schedule_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_schedule_fn::impl&+  schedule = asio_execution_schedule_fn::static_instance<>::instance;++} // namespace++template <typename S>+struct can_schedule :+  integral_constant<bool,+    asio_execution_schedule_fn::call_traits<S>::overload !=+      asio_execution_schedule_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S>+constexpr bool can_schedule_v = can_schedule<S>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S>+struct is_nothrow_schedule :+  integral_constant<bool,+    asio_execution_schedule_fn::call_traits<S>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S>+constexpr bool is_nothrow_schedule_v+  = is_nothrow_schedule<S>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SCHEDULE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/scheduler.hpp view
@@ -0,0 +1,91 @@+//+// execution/scheduler.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_SCHEDULER_HPP+#define ASIO_EXECUTION_SCHEDULER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/schedule.hpp"+#include "asio/traits/equality_comparable.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace execution {+namespace detail {++template <typename T>+struct is_scheduler_base :+  integral_constant<bool,+    is_copy_constructible<typename remove_cvref<T>::type>::value+      && traits::equality_comparable<typename remove_cvref<T>::type>::is_valid+  >+{+};++} // namespace detail++/// The is_scheduler trait detects whether a type T satisfies the+/// execution::scheduler concept.+/**+ * Class template @c is_scheduler is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a scheduler for+ * error type @c E, otherwise @c false_type.+ */+template <typename T>+struct is_scheduler :+#if defined(GENERATING_DOCUMENTATION)+  integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  conditional<+    can_schedule<T>::value,+    detail::is_scheduler_base<T>,+    false_type+  >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+ASIO_CONSTEXPR const bool is_scheduler_v = is_scheduler<T>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T>+ASIO_CONCEPT scheduler = is_scheduler<T>::value;++#define ASIO_EXECUTION_SCHEDULER ::asio::execution::scheduler++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_SCHEDULER typename++#endif // defined(ASIO_HAS_CONCEPTS)++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SCHEDULER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/sender.hpp view
@@ -0,0 +1,316 @@+//+// execution/sender.hpp+// ~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_SENDER_HPP+#define ASIO_EXECUTION_SENDER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/as_invocable.hpp"+#include "asio/execution/detail/void_receiver.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/receiver.hpp"++#include "asio/detail/push_options.hpp"++#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+  && defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  && defined(ASIO_HAS_DECLTYPE) \+  && !defined(ASIO_MSVC) || (_MSC_VER >= 1910)+# define ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT 1+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+       //   && defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   && defined(ASIO_HAS_DECLTYPE)+       //   && !defined(ASIO_MSVC) || (_MSC_VER >= 1910)++namespace asio {+namespace execution {+namespace detail {++namespace sender_base_ns { struct sender_base {}; }++template <typename S, typename = void>+struct sender_traits_base+{+  typedef void asio_execution_sender_traits_base_is_unspecialised;+};++template <typename S>+struct sender_traits_base<S,+    typename enable_if<+      is_base_of<sender_base_ns::sender_base, S>::value+    >::type>+{+};++template <typename S, typename = void, typename = void, typename = void>+struct has_sender_types : false_type+{+};++#if defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)++template <+    template <+      template <typename...> class Tuple,+      template <typename...> class Variant+    > class>+struct has_value_types+{+  typedef void type;+};++template <+  template <+    template <typename...> class Variant+  > class>+struct has_error_types+{+  typedef void type;+};++template <typename S>+struct has_sender_types<S,+    typename has_value_types<S::template value_types>::type,+    typename has_error_types<S::template error_types>::type,+    typename conditional<S::sends_done, void, void>::type> : true_type+{+};++template <typename S>+struct sender_traits_base<S,+    typename enable_if<+      has_sender_types<S>::value+    >::type>+{+  template <+      template <typename...> class Tuple,+      template <typename...> class Variant>+  using value_types = typename S::template value_types<Tuple, Variant>;++  template <template <typename...> class Variant>+  using error_types = typename S::template error_types<Variant>;++  ASIO_STATIC_CONSTEXPR(bool, sends_done = S::sends_done);+};++#endif // defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)++template <typename S>+struct sender_traits_base<S,+    typename enable_if<+      !has_sender_types<S>::value+        && detail::is_executor_of_impl<S,+          as_invocable<void_receiver, S> >::value+    >::type>+{+#if defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT) \+  && defined(ASIO_HAS_STD_EXCEPTION_PTR)++  template <+      template <typename...> class Tuple,+      template <typename...> class Variant>+  using value_types = Variant<Tuple<>>;++  template <template <typename...> class Variant>+  using error_types = Variant<std::exception_ptr>;++  ASIO_STATIC_CONSTEXPR(bool, sends_done = true);++#endif // defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)+       //   && defined(ASIO_HAS_STD_EXCEPTION_PTR)+};++} // namespace detail++/// Base class used for tagging senders.+#if defined(GENERATING_DOCUMENTATION)+typedef unspecified sender_base;+#else // defined(GENERATING_DOCUMENTATION)+typedef detail::sender_base_ns::sender_base sender_base;+#endif // defined(GENERATING_DOCUMENTATION)++/// Traits for senders.+template <typename S>+struct sender_traits+#if !defined(GENERATING_DOCUMENTATION)+  : detail::sender_traits_base<S>+#endif // !defined(GENERATING_DOCUMENTATION)+{+};++namespace detail {++template <typename S, typename = void>+struct has_sender_traits : true_type+{+};++template <typename S>+struct has_sender_traits<S,+    typename enable_if<+      is_same<+        typename asio::execution::sender_traits<+          S>::asio_execution_sender_traits_base_is_unspecialised,+        void+      >::value+    >::type> : false_type+{+};++} // namespace detail++/// The is_sender trait detects whether a type T satisfies the+/// execution::sender concept.++/**+ * Class template @c is_sender is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a sender,+ * otherwise @c false_type.+ */+template <typename T>+struct is_sender :+#if defined(GENERATING_DOCUMENTATION)+  integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  conditional<+    detail::has_sender_traits<typename remove_cvref<T>::type>::value,+    is_move_constructible<typename remove_cvref<T>::type>,+    false_type+  >::type+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+ASIO_CONSTEXPR const bool is_sender_v = is_sender<T>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T>+ASIO_CONCEPT sender = is_sender<T>::value;++#define ASIO_EXECUTION_SENDER ::asio::execution::sender++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_SENDER typename++#endif // defined(ASIO_HAS_CONCEPTS)++template <typename S, typename R>+struct can_connect;++/// The is_sender_to trait detects whether a type T satisfies the+/// execution::sender_to concept for some receiver.+/**+ * Class template @c is_sender_to is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a sender+ * for some receiver type R, otherwise @c false.+ */+template <typename T, typename R>+struct is_sender_to :+#if defined(GENERATING_DOCUMENTATION)+  integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  integral_constant<bool,+    is_sender<T>::value+      && is_receiver<R>::value+      && can_connect<T, R>::value+  >+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T, typename R>+ASIO_CONSTEXPR const bool is_sender_to_v =+  is_sender_to<T, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T, typename R>+ASIO_CONCEPT sender_to = is_sender_to<T, R>::value;++#define ASIO_EXECUTION_SENDER_TO(r) \+  ::asio::execution::sender_to<r>++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_SENDER_TO(r) typename++#endif // defined(ASIO_HAS_CONCEPTS)++/// The is_typed_sender trait detects whether a type T satisfies the+/// execution::typed_sender concept.+/**+ * Class template @c is_typed_sender is a type trait that is derived from @c+ * true_type if the type @c T meets the concept definition for a typed sender,+ * otherwise @c false.+ */+template <typename T>+struct is_typed_sender :+#if defined(GENERATING_DOCUMENTATION)+  integral_constant<bool, automatically_determined>+#else // defined(GENERATING_DOCUMENTATION)+  integral_constant<bool,+    is_sender<T>::value+      && detail::has_sender_types<+        sender_traits<typename remove_cvref<T>::type> >::value+  >+#endif // defined(GENERATING_DOCUMENTATION)+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename T>+ASIO_CONSTEXPR const bool is_typed_sender_v = is_typed_sender<T>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#if defined(ASIO_HAS_CONCEPTS)++template <typename T>+ASIO_CONCEPT typed_sender = is_typed_sender<T>::value;++#define ASIO_EXECUTION_TYPED_SENDER \+  ::asio::execution::typed_sender++#else // defined(ASIO_HAS_CONCEPTS)++#define ASIO_EXECUTION_TYPED_SENDER typename++#endif // defined(ASIO_HAS_CONCEPTS)++} // namespace execution+} // namespace asio++#include "asio/detail/pop_options.hpp"++#include "asio/execution/connect.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SENDER_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/set_done.hpp view
@@ -0,0 +1,255 @@+//+// execution/set_done.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_SET_DONE_HPP+#define ASIO_EXECUTION_SET_DONE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/traits/set_done_member.hpp"+#include "asio/traits/set_done_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that delivers a done notification to a receiver.+/**+ * The name <tt>execution::set_done</tt> denotes a customisation point object.+ * The expression <tt>execution::set_done(R)</tt> for some subexpression+ * <tt>R</tt> is expression-equivalent to:+ *+ * @li <tt>R.set_done()</tt>, if that expression is valid. If the function+ *   selected does not signal the receiver <tt>R</tt>'s done channel, the+ *   program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>set_done(R)</tt>, if that expression is valid, with+ * overload resolution performed in a context that includes the declaration+ * <tt>void set_done();</tt> and that does not include a declaration of+ * <tt>execution::set_done</tt>. If the function selected by overload+ * resolution does not signal the receiver <tt>R</tt>'s done channel, the+ * program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>execution::set_done(R)</tt> is ill-formed.+ */+inline constexpr unspecified set_done = unspecified;++/// A type trait that determines whether a @c set_done expression is+/// well-formed.+/**+ * Class template @c can_set_done is a trait that is derived from+ * @c true_type if the expression <tt>execution::set_done(std::declval<R>(),+ * std::declval<E>())</tt> is well formed; otherwise @c false_type.+ */+template <typename R>+struct can_set_done :+  integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_set_done_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::traits::set_done_free;+using asio::traits::set_done_member;++void set_done();++enum overload_type+{+  call_member,+  call_free,+  ill_formed+};++template <typename R, typename = void, typename = void>+struct call_traits+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++template <typename R>+struct call_traits<R,+  typename enable_if<+    set_done_member<R>::is_valid+  >::type> :+  set_done_member<R>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename R>+struct call_traits<R,+  typename enable_if<+    !set_done_member<R>::is_valid+  >::type,+  typename enable_if<+    set_done_free<R>::is_valid+  >::type> :+  set_done_free<R>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R>::overload == call_member,+    typename call_traits<R>::result_type+  >::type+  operator()(R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R>::is_noexcept))+  {+    return ASIO_MOVE_CAST(R)(r).set_done();+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R>::overload == call_free,+    typename call_traits<R>::result_type+  >::type+  operator()(R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R>::is_noexcept))+  {+    return set_done(ASIO_MOVE_CAST(R)(r));+  }+#else // defined(ASIO_HAS_MOVE)+  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&>::overload == call_member,+    typename call_traits<R&>::result_type+  >::type+  operator()(R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&>::is_noexcept))+  {+    return r.set_done();+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&>::overload == call_member,+    typename call_traits<const R&>::result_type+  >::type+  operator()(const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&>::is_noexcept))+  {+    return r.set_done();+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&>::overload == call_free,+    typename call_traits<R&>::result_type+  >::type+  operator()(R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&>::is_noexcept))+  {+    return set_done(r);+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&>::overload == call_free,+    typename call_traits<const R&>::result_type+  >::type+  operator()(const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&>::is_noexcept))+  {+    return set_done(r);+  }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+  static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_set_done_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_set_done_fn::impl&+  set_done = asio_execution_set_done_fn::static_instance<>::instance;++} // namespace++template <typename R>+struct can_set_done :+  integral_constant<bool,+    asio_execution_set_done_fn::call_traits<R>::overload !=+      asio_execution_set_done_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+constexpr bool can_set_done_v = can_set_done<R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+struct is_nothrow_set_done :+  integral_constant<bool,+    asio_execution_set_done_fn::call_traits<R>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+constexpr bool is_nothrow_set_done_v+  = is_nothrow_set_done<R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SET_DONE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/set_error.hpp view
@@ -0,0 +1,255 @@+//+// execution/set_error.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_SET_ERROR_HPP+#define ASIO_EXECUTION_SET_ERROR_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/traits/set_error_member.hpp"+#include "asio/traits/set_error_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that delivers an error notification to a receiver.+/**+ * The name <tt>execution::set_error</tt> denotes a customisation point object.+ * The expression <tt>execution::set_error(R, E)</tt> for some subexpressions+ * <tt>R</tt> and <tt>E</tt> are expression-equivalent to:+ *+ * @li <tt>R.set_error(E)</tt>, if that expression is valid. If the function+ *   selected does not send the error <tt>E</tt> to the receiver <tt>R</tt>'s+ *   error channel, the program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>set_error(R, E)</tt>, if that expression is valid, with+ *   overload resolution performed in a context that includes the declaration+ *   <tt>void set_error();</tt> and that does not include a declaration of+ *   <tt>execution::set_error</tt>. If the function selected by overload+ *   resolution does not send the error <tt>E</tt> to the receiver <tt>R</tt>'s+ *   error channel, the program is ill-formed with no diagnostic required.+ *+ * @li Otherwise, <tt>execution::set_error(R, E)</tt> is ill-formed.+ */+inline constexpr unspecified set_error = unspecified;++/// A type trait that determines whether a @c set_error expression is+/// well-formed.+/**+ * Class template @c can_set_error is a trait that is derived from+ * @c true_type if the expression <tt>execution::set_error(std::declval<R>(),+ * std::declval<E>())</tt> is well formed; otherwise @c false_type.+ */+template <typename R, typename E>+struct can_set_error :+  integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_set_error_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::traits::set_error_free;+using asio::traits::set_error_member;++void set_error();++enum overload_type+{+  call_member,+  call_free,+  ill_formed+};++template <typename R, typename E, typename = void, typename = void>+struct call_traits+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++template <typename R, typename E>+struct call_traits<R, void(E),+  typename enable_if<+    set_error_member<R, E>::is_valid+  >::type> :+  set_error_member<R, E>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename R, typename E>+struct call_traits<R, void(E),+  typename enable_if<+    !set_error_member<R, E>::is_valid+  >::type,+  typename enable_if<+    set_error_free<R, E>::is_valid+  >::type> :+  set_error_free<R, E>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+  template <typename R, typename E>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R, void(E)>::overload == call_member,+    typename call_traits<R, void(E)>::result_type+  >::type+  operator()(R&& r, E&& e) const+    ASIO_NOEXCEPT_IF((+      call_traits<R, void(E)>::is_noexcept))+  {+    return ASIO_MOVE_CAST(R)(r).set_error(ASIO_MOVE_CAST(E)(e));+  }++  template <typename R, typename E>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R, void(E)>::overload == call_free,+    typename call_traits<R, void(E)>::result_type+  >::type+  operator()(R&& r, E&& e) const+    ASIO_NOEXCEPT_IF((+      call_traits<R, void(E)>::is_noexcept))+  {+    return set_error(ASIO_MOVE_CAST(R)(r), ASIO_MOVE_CAST(E)(e));+  }+#else // defined(ASIO_HAS_MOVE)+  template <typename R, typename E>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&, void(const E&)>::overload == call_member,+    typename call_traits<R&, void(const E&)>::result_type+  >::type+  operator()(R& r, const E& e) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&, void(const E&)>::is_noexcept))+  {+    return r.set_error(e);+  }++  template <typename R, typename E>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&, void(const E&)>::overload == call_member,+    typename call_traits<const R&, void(const E&)>::result_type+  >::type+  operator()(const R& r, const E& e) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&, void(const E&)>::is_noexcept))+  {+    return r.set_error(e);+  }++  template <typename R, typename E>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&, void(const E&)>::overload == call_free,+    typename call_traits<R&, void(const E&)>::result_type+  >::type+  operator()(R& r, const E& e) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&, void(const E&)>::is_noexcept))+  {+    return set_error(r, e);+  }++  template <typename R, typename E>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&, void(const E&)>::overload == call_free,+    typename call_traits<const R&, void(const E&)>::result_type+  >::type+  operator()(const R& r, const E& e) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&, void(const E&)>::is_noexcept))+  {+    return set_error(r, e);+  }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+  static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_set_error_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_set_error_fn::impl&+  set_error = asio_execution_set_error_fn::static_instance<>::instance;++} // namespace++template <typename R, typename E>+struct can_set_error :+  integral_constant<bool,+    asio_execution_set_error_fn::call_traits<R, void(E)>::overload !=+      asio_execution_set_error_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename E>+constexpr bool can_set_error_v = can_set_error<R, E>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename E>+struct is_nothrow_set_error :+  integral_constant<bool,+    asio_execution_set_error_fn::call_traits<R, void(E)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename E>+constexpr bool is_nothrow_set_error_v+  = is_nothrow_set_error<R, E>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SET_ERROR_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/set_value.hpp view
@@ -0,0 +1,488 @@+//+// execution/set_value.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_SET_VALUE_HPP+#define ASIO_EXECUTION_SET_VALUE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"+#include "asio/traits/set_value_member.hpp"+#include "asio/traits/set_value_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that delivers a value to a receiver.+/**+ * The name <tt>execution::set_value</tt> denotes a customisation point object.+ * The expression <tt>execution::set_value(R, Vs...)</tt> for some+ * subexpressions <tt>R</tt> and <tt>Vs...</tt> is expression-equivalent to:+ *+ * @li <tt>R.set_value(Vs...)</tt>, if that expression is valid. If the+ *   function selected does not send the value(s) <tt>Vs...</tt> to the receiver+ *   <tt>R</tt>'s value channel, the program is ill-formed with no diagnostic+ *   required.+ *+ * @li Otherwise, <tt>set_value(R, Vs...)</tt>, if that expression is valid,+ *   with overload resolution performed in a context that includes the+ *   declaration <tt>void set_value();</tt> and that does not include a+ *   declaration of <tt>execution::set_value</tt>. If the function selected by+ *   overload resolution does not send the value(s) <tt>Vs...</tt> to the+ *   receiver <tt>R</tt>'s value channel, the program is ill-formed with no+ *   diagnostic required.+ *+ * @li Otherwise, <tt>execution::set_value(R, Vs...)</tt> is ill-formed.+ */+inline constexpr unspecified set_value = unspecified;++/// A type trait that determines whether a @c set_value expression is+/// well-formed.+/**+ * Class template @c can_set_value is a trait that is derived from+ * @c true_type if the expression <tt>execution::set_value(std::declval<R>(),+ * std::declval<Vs>()...)</tt> is well formed; otherwise @c false_type.+ */+template <typename R, typename... Vs>+struct can_set_value :+  integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_set_value_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::traits::set_value_free;+using asio::traits::set_value_member;++void set_value();++enum overload_type+{+  call_member,+  call_free,+  ill_formed+};++template <typename R, typename Vs, typename = void, typename = void>+struct call_traits+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++template <typename R, typename Vs>+struct call_traits<R, Vs,+  typename enable_if<+    set_value_member<R, Vs>::is_valid+  >::type> :+  set_value_member<R, Vs>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename R, typename Vs>+struct call_traits<R, Vs,+  typename enable_if<+    !set_value_member<R, Vs>::is_valid+  >::type,+  typename enable_if<+    set_value_free<R, Vs>::is_valid+  >::type> :+  set_value_free<R, Vs>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++struct impl+{+#if defined(ASIO_HAS_MOVE)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename R, typename... Vs>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R, void(Vs...)>::overload == call_member,+    typename call_traits<R, void(Vs...)>::result_type+  >::type+  operator()(R&& r, Vs&&... v) const+    ASIO_NOEXCEPT_IF((+      call_traits<R, void(Vs...)>::is_noexcept))+  {+    return ASIO_MOVE_CAST(R)(r).set_value(ASIO_MOVE_CAST(Vs)(v)...);+  }++  template <typename R, typename... Vs>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R, void(Vs...)>::overload == call_free,+    typename call_traits<R, void(Vs...)>::result_type+  >::type+  operator()(R&& r, Vs&&... v) const+    ASIO_NOEXCEPT_IF((+      call_traits<R, void(Vs...)>::is_noexcept))+  {+    return set_value(ASIO_MOVE_CAST(R)(r),+        ASIO_MOVE_CAST(Vs)(v)...);+  }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R, void()>::overload == call_member,+    typename call_traits<R, void()>::result_type+  >::type+  operator()(R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R, void()>::is_noexcept))+  {+    return ASIO_MOVE_CAST(R)(r).set_value();+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R, void()>::overload == call_free,+    typename call_traits<R, void()>::result_type+  >::type+  operator()(R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R, void()>::is_noexcept))+  {+    return set_value(ASIO_MOVE_CAST(R)(r));+  }++#define ASIO_PRIVATE_SET_VALUE_CALL_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  ASIO_CONSTEXPR typename enable_if< \+    call_traits<R, \+      void(ASIO_VARIADIC_TARGS(n))>::overload == call_member, \+    typename call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::result_type \+  >::type \+  operator()(R&& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    ASIO_NOEXCEPT_IF(( \+      call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+  { \+    return ASIO_MOVE_CAST(R)(r).set_value( \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  ASIO_CONSTEXPR typename enable_if< \+    call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::overload == call_free, \+    typename call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::result_type \+  >::type \+  operator()(R&& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    ASIO_NOEXCEPT_IF(( \+      call_traits<R, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+  { \+    return set_value(ASIO_MOVE_CAST(R)(r), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_CALL_DEF)+#undef ASIO_PRIVATE_SET_VALUE_CALL_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#else // defined(ASIO_HAS_MOVE)++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename R, typename... Vs>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&, void(const Vs&...)>::overload == call_member,+    typename call_traits<R&, void(const Vs&...)>::result_type+  >::type+  operator()(R& r, const Vs&... v) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&, void(const Vs&...)>::is_noexcept))+  {+    return r.set_value(v...);+  }++  template <typename R, typename... Vs>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&, void(const Vs&...)>::overload == call_member,+    typename call_traits<const R&, void(const Vs&...)>::result_type+  >::type+  operator()(const R& r, const Vs&... v) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&, void(const Vs&...)>::is_noexcept))+  {+    return r.set_value(v...);+  }++  template <typename R, typename... Vs>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&, void(const Vs&...)>::overload == call_free,+    typename call_traits<R&, void(const Vs&...)>::result_type+  >::type+  operator()(R& r, const Vs&... v) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&, void(const Vs&...)>::is_noexcept))+  {+    return set_value(r, v...);+  }++  template <typename R, typename... Vs>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&, void(const Vs&...)>::overload == call_free,+    typename call_traits<const R&, void(const Vs&...)>::result_type+  >::type+  operator()(const R& r, const Vs&... v) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&, void(const Vs&...)>::is_noexcept))+  {+    return set_value(r, v...);+  }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&, void()>::overload == call_member,+    typename call_traits<R&, void()>::result_type+  >::type+  operator()(R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&, void()>::is_noexcept))+  {+    return r.set_value();+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&, void()>::overload == call_member,+    typename call_traits<const R&, void()>::result_type+  >::type+  operator()(const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&, void()>::is_noexcept))+  {+    return r.set_value();+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&, void()>::overload == call_free,+    typename call_traits<R&, void()>::result_type+  >::type+  operator()(R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&, void()>::is_noexcept))+  {+    return set_value(r);+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&, void()>::overload == call_free,+    typename call_traits<const R&, void()>::result_type+  >::type+  operator()(const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&, void()>::is_noexcept))+  {+    return set_value(r);+  }++#define ASIO_PRIVATE_SET_VALUE_CALL_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  ASIO_CONSTEXPR typename enable_if< \+    call_traits<R&, \+      void(ASIO_VARIADIC_TARGS(n))>::overload == call_member, \+    typename call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::result_type \+  >::type \+  operator()(R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    ASIO_NOEXCEPT_IF(( \+      call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+  { \+    return r.set_value(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  ASIO_CONSTEXPR typename enable_if< \+    call_traits<const R&, \+      void(ASIO_VARIADIC_TARGS(n))>::overload == call_member, \+    typename call_traits<const R&, \+      void(ASIO_VARIADIC_TARGS(n))>::result_type \+  >::type \+  operator()(const R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    ASIO_NOEXCEPT_IF(( \+      call_traits<const R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+  { \+    return r.set_value(ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  ASIO_CONSTEXPR typename enable_if< \+    call_traits<R&, \+      void(ASIO_VARIADIC_TARGS(n))>::overload == call_free, \+    typename call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::result_type \+  >::type \+  operator()(R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    ASIO_NOEXCEPT_IF(( \+      call_traits<R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+  { \+    return set_value(r, ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  ASIO_CONSTEXPR typename enable_if< \+    call_traits<const R&, \+      void(ASIO_VARIADIC_TARGS(n))>::overload == call_free, \+    typename call_traits<const R&, \+      void(ASIO_VARIADIC_TARGS(n))>::result_type \+  >::type \+  operator()(const R& r, ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    ASIO_NOEXCEPT_IF(( \+      call_traits<const R&, void(ASIO_VARIADIC_TARGS(n))>::is_noexcept)) \+  { \+    return set_value(r, ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_CALL_DEF)+#undef ASIO_PRIVATE_SET_VALUE_CALL_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+  static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_set_value_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_set_value_fn::impl&+  set_value = asio_execution_set_value_fn::static_instance<>::instance;++} // namespace++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename R, typename... Vs>+struct can_set_value :+  integral_constant<bool,+    asio_execution_set_value_fn::call_traits<R, void(Vs...)>::overload !=+      asio_execution_set_value_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename... Vs>+constexpr bool can_set_value_v = can_set_value<R, Vs...>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename... Vs>+struct is_nothrow_set_value :+  integral_constant<bool,+    asio_execution_set_value_fn::call_traits<R, void(Vs...)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R, typename... Vs>+constexpr bool is_nothrow_set_value_v+  = is_nothrow_set_value<R, Vs...>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename R, typename = void,+    typename = void, typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void, typename = void>+struct can_set_value;++template <typename R, typename = void,+    typename = void, typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void, typename = void>+struct is_nothrow_set_value;++template <typename R>+struct can_set_value<R> :+  integral_constant<bool,+    asio_execution_set_value_fn::call_traits<R, void()>::overload !=+      asio_execution_set_value_fn::ill_formed>+{+};++template <typename R>+struct is_nothrow_set_value<R> :+  integral_constant<bool,+    asio_execution_set_value_fn::call_traits<R, void()>::is_noexcept>+{+};++#define ASIO_PRIVATE_SET_VALUE_TRAITS_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct can_set_value<R, ASIO_VARIADIC_TARGS(n)> : \+    integral_constant<bool, \+      asio_execution_set_value_fn::call_traits<R, \+        void(ASIO_VARIADIC_TARGS(n))>::overload != \+          asio_execution_set_value_fn::ill_formed> \+  { \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct is_nothrow_set_value<R, ASIO_VARIADIC_TARGS(n)> : \+    integral_constant<bool, \+      asio_execution_set_value_fn::call_traits<R, \+        void(ASIO_VARIADIC_TARGS(n))>::is_noexcept> \+  { \+  }; \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_TRAITS_DEF)+#undef ASIO_PRIVATE_SET_VALUE_TRAITS_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SET_VALUE_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/start.hpp view
@@ -0,0 +1,252 @@+//+// execution/start.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_START_HPP+#define ASIO_EXECUTION_START_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/traits/start_member.hpp"+#include "asio/traits/start_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that notifies an operation state object to start+/// its associated operation.+/**+ * The name <tt>execution::start</tt> denotes a customisation point object.+ * The expression <tt>execution::start(R)</tt> for some subexpression+ * <tt>R</tt> is expression-equivalent to:+ *+ * @li <tt>R.start()</tt>, if that expression is valid.+ *+ * @li Otherwise, <tt>start(R)</tt>, if that expression is valid, with+ * overload resolution performed in a context that includes the declaration+ * <tt>void start();</tt> and that does not include a declaration of+ * <tt>execution::start</tt>.+ *+ * @li Otherwise, <tt>execution::start(R)</tt> is ill-formed.+ */+inline constexpr unspecified start = unspecified;++/// A type trait that determines whether a @c start expression is+/// well-formed.+/**+ * Class template @c can_start is a trait that is derived from+ * @c true_type if the expression <tt>execution::start(std::declval<R>(),+ * std::declval<E>())</tt> is well formed; otherwise @c false_type.+ */+template <typename R>+struct can_start :+  integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_start_fn {++using asio::decay;+using asio::declval;+using asio::enable_if;+using asio::traits::start_free;+using asio::traits::start_member;++void start();++enum overload_type+{+  call_member,+  call_free,+  ill_formed+};++template <typename R, typename = void, typename = void>+struct call_traits+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++template <typename R>+struct call_traits<R,+  typename enable_if<+    start_member<R>::is_valid+  >::type> :+  start_member<R>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename R>+struct call_traits<R,+  typename enable_if<+    !start_member<R>::is_valid+  >::type,+  typename enable_if<+    start_free<R>::is_valid+  >::type> :+  start_free<R>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R>::overload == call_member,+    typename call_traits<R>::result_type+  >::type+  operator()(R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R>::is_noexcept))+  {+    return ASIO_MOVE_CAST(R)(r).start();+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R>::overload == call_free,+    typename call_traits<R>::result_type+  >::type+  operator()(R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R>::is_noexcept))+  {+    return start(ASIO_MOVE_CAST(R)(r));+  }+#else // defined(ASIO_HAS_MOVE)+  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&>::overload == call_member,+    typename call_traits<R&>::result_type+  >::type+  operator()(R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&>::is_noexcept))+  {+    return r.start();+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&>::overload == call_member,+    typename call_traits<const R&>::result_type+  >::type+  operator()(const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&>::is_noexcept))+  {+    return r.start();+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<R&>::overload == call_free,+    typename call_traits<R&>::result_type+  >::type+  operator()(R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<R&>::is_noexcept))+  {+    return start(r);+  }++  template <typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const R&>::overload == call_free,+    typename call_traits<const R&>::result_type+  >::type+  operator()(const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const R&>::is_noexcept))+  {+    return start(r);+  }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+  static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_start_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_start_fn::impl&+  start = asio_execution_start_fn::static_instance<>::instance;++} // namespace++template <typename R>+struct can_start :+  integral_constant<bool,+    asio_execution_start_fn::call_traits<R>::overload !=+      asio_execution_start_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+constexpr bool can_start_v = can_start<R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+struct is_nothrow_start :+  integral_constant<bool,+    asio_execution_start_fn::call_traits<R>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename R>+constexpr bool is_nothrow_start_v+  = is_nothrow_start<R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_START_HPP
+ link/modules/asio-standalone/asio/include/asio/execution/submit.hpp view
@@ -0,0 +1,455 @@+//+// execution/submit.hpp+// ~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXECUTION_SUBMIT_HPP+#define ASIO_EXECUTION_SUBMIT_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include "asio/detail/type_traits.hpp"+#include "asio/execution/detail/submit_receiver.hpp"+#include "asio/execution/executor.hpp"+#include "asio/execution/receiver.hpp"+#include "asio/execution/sender.hpp"+#include "asio/execution/start.hpp"+#include "asio/traits/submit_member.hpp"+#include "asio/traits/submit_free.hpp"++#include "asio/detail/push_options.hpp"++#if defined(GENERATING_DOCUMENTATION)++namespace asio {+namespace execution {++/// A customisation point that submits a sender to a receiver.+/**+ * The name <tt>execution::submit</tt> denotes a customisation point object. For+ * some subexpressions <tt>s</tt> and <tt>r</tt>, let <tt>S</tt> be a type such+ * that <tt>decltype((s))</tt> is <tt>S</tt> and let <tt>R</tt> be a type such+ * that <tt>decltype((r))</tt> is <tt>R</tt>. The expression+ * <tt>execution::submit(s, r)</tt> is ill-formed if <tt>sender_to<S, R></tt> is+ * not <tt>true</tt>. Otherwise, it is expression-equivalent to:+ *+ * @li <tt>s.submit(r)</tt>, if that expression is valid and <tt>S</tt> models+ *   <tt>sender</tt>. If the function selected does not submit the receiver+ *   object <tt>r</tt> via the sender <tt>s</tt>, the program is ill-formed with+ *   no diagnostic required.+ *+ * @li Otherwise, <tt>submit(s, r)</tt>, if that expression is valid and+ *   <tt>S</tt> models <tt>sender</tt>, with overload resolution performed in a+ *   context that includes the declaration <tt>void submit();</tt> and that does+ *   not include a declaration of <tt>execution::submit</tt>. If the function+ *   selected by overload resolution does not submit the receiver object+ *   <tt>r</tt> via the sender <tt>s</tt>, the program is ill-formed with no+ *   diagnostic required.+ *+ * @li Otherwise, <tt>execution::start((new submit_receiver<S,+ *   R>{s,r})->state_)</tt>, where <tt>submit_receiver</tt> is an+ *   implementation-defined class template equivalent to:+ *   @code template<class S, class R>+ *   struct submit_receiver {+ *     struct wrap {+ *       submit_receiver * p_;+ *       template<class...As>+ *         requires receiver_of<R, As...>+ *       void set_value(As&&... as) &&+ *         noexcept(is_nothrow_receiver_of_v<R, As...>) {+ *         execution::set_value(std::move(p_->r_), (As&&) as...);+ *         delete p_;+ *       }+ *       template<class E>+ *         requires receiver<R, E>+ *       void set_error(E&& e) && noexcept {+ *         execution::set_error(std::move(p_->r_), (E&&) e);+ *         delete p_;+ *       }+ *       void set_done() && noexcept {+ *         execution::set_done(std::move(p_->r_));+ *         delete p_;+ *       }+ *     };+ *     remove_cvref_t<R> r_;+ *     connect_result_t<S, wrap> state_;+ *     submit_receiver(S&& s, R&& r)+ *       : r_((R&&) r)+ *       , state_(execution::connect((S&&) s, wrap{this})) {}+ *   };+ *   @endcode+ */+inline constexpr unspecified submit = unspecified;++/// A type trait that determines whether a @c submit expression is+/// well-formed.+/**+ * Class template @c can_submit is a trait that is derived from+ * @c true_type if the expression <tt>execution::submit(std::declval<R>(),+ * std::declval<E>())</tt> is well formed; otherwise @c false_type.+ */+template <typename S, typename R>+struct can_submit :+  integral_constant<bool, automatically_determined>+{+};++} // namespace execution+} // namespace asio++#else // defined(GENERATING_DOCUMENTATION)++namespace asio_execution_submit_fn {++using asio::declval;+using asio::enable_if;+using asio::execution::is_sender_to;+using asio::traits::submit_free;+using asio::traits::submit_member;++void submit();++enum overload_type+{+  call_member,+  call_free,+  adapter,+  ill_formed+};++template <typename S, typename R, typename = void,+    typename = void, typename = void>+struct call_traits+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++template <typename S, typename R>+struct call_traits<S, void(R),+  typename enable_if<+    submit_member<S, R>::is_valid+  >::type,+  typename enable_if<+    is_sender_to<S, R>::value+  >::type> :+  submit_member<S, R>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member);+};++template <typename S, typename R>+struct call_traits<S, void(R),+  typename enable_if<+    !submit_member<S, R>::is_valid+  >::type,+  typename enable_if<+    submit_free<S, R>::is_valid+  >::type,+  typename enable_if<+    is_sender_to<S, R>::value+  >::type> :+  submit_free<S, R>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free);+};++template <typename S, typename R>+struct call_traits<S, void(R),+  typename enable_if<+    !submit_member<S, R>::is_valid+  >::type,+  typename enable_if<+    !submit_free<S, R>::is_valid+  >::type,+  typename enable_if<+    is_sender_to<S, R>::value+  >::type>+{+  ASIO_STATIC_CONSTEXPR(overload_type, overload = adapter);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef void result_type;+};++struct impl+{+#if defined(ASIO_HAS_MOVE)+  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(R)>::overload == call_member,+    typename call_traits<S, void(R)>::result_type+  >::type+  operator()(S&& s, R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(R)>::is_noexcept))+  {+    return ASIO_MOVE_CAST(S)(s).submit(ASIO_MOVE_CAST(R)(r));+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(R)>::overload == call_free,+    typename call_traits<S, void(R)>::result_type+  >::type+  operator()(S&& s, R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(R)>::is_noexcept))+  {+    return submit(ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S, void(R)>::overload == adapter,+    typename call_traits<S, void(R)>::result_type+  >::type+  operator()(S&& s, R&& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S, void(R)>::is_noexcept))+  {+    return asio::execution::start(+        (new asio::execution::detail::submit_receiver<S, R>(+          ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r)))->state_);+  }+#else // defined(ASIO_HAS_MOVE)+  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(R&)>::overload == call_member,+    typename call_traits<S&, void(R&)>::result_type+  >::type+  operator()(S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(R&)>::is_noexcept))+  {+    return s.submit(r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(R&)>::overload == call_member,+    typename call_traits<const S&, void(R&)>::result_type+  >::type+  operator()(const S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(R&)>::is_noexcept))+  {+    return s.submit(r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(R&)>::overload == call_free,+    typename call_traits<S&, void(R&)>::result_type+  >::type+  operator()(S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(R&)>::is_noexcept))+  {+    return submit(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(R&)>::overload == call_free,+    typename call_traits<const S&, void(R&)>::result_type+  >::type+  operator()(const S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(R&)>::is_noexcept))+  {+    return submit(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(R&)>::overload == adapter,+    typename call_traits<S&, void(R&)>::result_type+  >::type+  operator()(S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(R&)>::is_noexcept))+  {+    return asio::execution::start(+        (new asio::execution::detail::submit_receiver<+          S&, R&>(s, r))->state_);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(R&)>::overload == adapter,+    typename call_traits<const S&, void(R&)>::result_type+  >::type+  operator()(const S& s, R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(R&)>::is_noexcept))+  {+    asio::execution::start(+        (new asio::execution::detail::submit_receiver<+          const S&, R&>(s, r))->state_);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(const R&)>::overload == call_member,+    typename call_traits<S&, void(const R&)>::result_type+  >::type+  operator()(S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(const R&)>::is_noexcept))+  {+    return s.submit(r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(const R&)>::overload == call_member,+    typename call_traits<const S&, void(const R&)>::result_type+  >::type+  operator()(const S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(const R&)>::is_noexcept))+  {+    return s.submit(r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(const R&)>::overload == call_free,+    typename call_traits<S&, void(const R&)>::result_type+  >::type+  operator()(S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(const R&)>::is_noexcept))+  {+    return submit(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(const R&)>::overload == call_free,+    typename call_traits<const S&, void(const R&)>::result_type+  >::type+  operator()(const S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(const R&)>::is_noexcept))+  {+    return submit(s, r);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<S&, void(const R&)>::overload == adapter,+    typename call_traits<S&, void(const R&)>::result_type+  >::type+  operator()(S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<S&, void(const R&)>::is_noexcept))+  {+    asio::execution::start(+        (new asio::execution::detail::submit_receiver<+          S&, const R&>(s, r))->state_);+  }++  template <typename S, typename R>+  ASIO_CONSTEXPR typename enable_if<+    call_traits<const S&, void(const R&)>::overload == adapter,+    typename call_traits<const S&, void(const R&)>::result_type+  >::type+  operator()(const S& s, const R& r) const+    ASIO_NOEXCEPT_IF((+      call_traits<const S&, void(const R&)>::is_noexcept))+  {+    asio::execution::start(+        (new asio::execution::detail::submit_receiver<+          const S&, const R&>(s, r))->state_);+  }+#endif // defined(ASIO_HAS_MOVE)+};++template <typename T = impl>+struct static_instance+{+  static const T instance;+};++template <typename T>+const T static_instance<T>::instance = {};++} // namespace asio_execution_submit_fn+namespace asio {+namespace execution {+namespace {++static ASIO_CONSTEXPR const asio_execution_submit_fn::impl&+  submit = asio_execution_submit_fn::static_instance<>::instance;++} // namespace++template <typename S, typename R>+struct can_submit :+  integral_constant<bool,+    asio_execution_submit_fn::call_traits<S, void(R)>::overload !=+      asio_execution_submit_fn::ill_formed>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+constexpr bool can_submit_v = can_submit<S, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+struct is_nothrow_submit :+  integral_constant<bool,+    asio_execution_submit_fn::call_traits<S, void(R)>::is_noexcept>+{+};++#if defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+constexpr bool is_nothrow_submit_v+  = is_nothrow_submit<S, R>::value;++#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)++template <typename S, typename R>+struct submit_result+{+  typedef typename asio_execution_submit_fn::call_traits<+      S, void(R)>::result_type type;+};++namespace detail {++template <typename S, typename R>+void submit_helper(ASIO_MOVE_ARG(S) s, ASIO_MOVE_ARG(R) r)+{+  execution::submit(ASIO_MOVE_CAST(S)(s), ASIO_MOVE_CAST(R)(r));+}++} // namespace detail+} // namespace execution+} // namespace asio++#endif // defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_EXECUTION_SUBMIT_HPP
link/modules/asio-standalone/asio/include/asio/execution_context.hpp view
@@ -2,7 +2,7 @@ // execution_context.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,8 +19,8 @@ #include <cstddef> #include <stdexcept> #include <typeinfo>-#include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp" @@ -106,51 +106,13 @@   : private noncopyable { public:-  template <typename T> class allocator;   class id;   class service;-  class service_maker;  public:   /// Constructor.   ASIO_DECL execution_context(); -  /// Constructor.-  /**-   * @param a An allocator that will be used for allocating objects that are-   * associated with the context, such as services and internal state for I/O-   * objects.-   */-  template <typename Allocator>-  execution_context(allocator_arg_t, const Allocator& a);--  /// Constructor.-  /**-   * Construct with a service maker, to create an initial set of services that-   * will be installed into the execution context at construction time.-   *-   * @param initial_services Used to create the initial services. The @c make-   * function will be called once at the end of execution_context construction.-   */-  ASIO_DECL explicit execution_context(-      const service_maker& initial_services);--  /// Constructor.-  /**-   * Construct with a service maker, to create an initial set of services that-   * will be installed into the execution context at construction time.-   *-   * @param a An allocator that will be used for allocating objects that are-   * associated with the context, such as services and internal state for I/O-   * objects.-   *-   * @param initial_services Used to create the initial services. The @c make-   * function will be called once at the end of execution_context construction.-   */-  template <typename Allocator>-  execution_context(allocator_arg_t, const Allocator& a,-      const service_maker& initial_services);-   /// Destructor.   ASIO_DECL ~execution_context(); @@ -262,6 +224,8 @@   template <typename Service>   friend Service& use_service(io_context& ioc); +#if defined(GENERATING_DOCUMENTATION)+   /// Creates a service object and adds it to the execution_context.   /**    * This function is used to add a service to the execution_context.@@ -277,6 +241,27 @@   template <typename Service, typename... Args>   friend Service& make_service(execution_context& e, Args&&... args); +#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename Service, typename... Args>+  friend Service& make_service(execution_context& e,+      ASIO_MOVE_ARG(Args)... args);++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename Service>+  friend Service& make_service(execution_context& e);++#define ASIO_PRIVATE_MAKE_SERVICE_DEF(n) \+  template <typename Service, ASIO_VARIADIC_TPARAMS(n)> \+  friend Service& make_service(execution_context& e, \+      ASIO_VARIADIC_MOVE_PARAMS(n)); \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_MAKE_SERVICE_DEF)+#undef ASIO_PRIVATE_MAKE_SERVICE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+   /// (Deprecated: Use make_service().) Add a service object to the   /// execution_context.   /**@@ -313,150 +298,8 @@   friend bool has_service(execution_context& e);  private:-  class allocator_impl_base;-  template <typename Allocator> class allocator_impl;--  // Helper constructors to perform non-templated parts of context construction.-  ASIO_DECL explicit execution_context(allocator_impl_base* alloc);-  ASIO_DECL execution_context(allocator_impl_base* alloc,-      const service_maker& initial_services);--  // The allocator used for all services and other context-wide allocations.-  struct auto_allocator_ptr-  {-    allocator_impl_base* ptr_;-    ~auto_allocator_ptr();-  } allocator_;-   // The service registry.-  detail::service_registry* service_registry_;-};--class execution_context::allocator_impl_base-{-public:-  virtual void destroy() = 0;-  virtual void* allocate(std::size_t size, std::size_t align) = 0;-  virtual void deallocate(void* ptr, std::size_t size, std::size_t align) = 0;--protected:-  ASIO_DECL virtual ~allocator_impl_base();-};--template <typename Allocator>-class execution_context::allocator_impl-  : public execution_context::allocator_impl_base-{-public:-  allocator_impl(const Allocator& alloc) : allocator_(alloc) {}-  void destroy();-  void* allocate(std::size_t size, std::size_t align);-  void deallocate(void* ptr, std::size_t size, std::size_t align);--private:-  Allocator allocator_;-};--template <typename T>-class execution_context::allocator-{-public:-  /// The type of objects that may be allocated by the allocator.-  typedef T value_type;--  /// Rebinds an allocator to another value type.-  template <typename U>-  struct rebind-  {-    /// Specifies the type of the rebound allocator.-    typedef allocator<U> other;-  };--  /// Construct an allocator that is associated with an execution context.-  explicit constexpr allocator(execution_context& e) noexcept-    : impl_(e.allocator_.ptr_)-  {-  }--  /// Construct from another @c allocator for a different value type.-  template <typename U>-  constexpr allocator(const allocator<U>& a) noexcept-    : impl_(a.impl_)-  {-  }--  /// Equality operator.-  constexpr bool operator==(const allocator& other) const noexcept-  {-    return impl_ == other.impl_;-  }--  /// Inequality operator.-  constexpr bool operator!=(const allocator& other) const noexcept-  {-    return impl_ != other.impl_;-  }--  /// Allocate space for @c n objects of the allocator's value type.-  T* allocate(std::size_t n) const-  {-    return static_cast<T*>(impl_->allocate(sizeof(T) * n, alignof(T)));-  }--  /// Deallocate space for @c n objects of the allocator's value type.-  void deallocate(T* p, std::size_t n) const-  {-    impl_->deallocate(p, sizeof(T) * n, alignof(T));-  }--private:-  template <typename> friend class execution_context::allocator;-  allocator_impl_base* impl_;-};--template <>-class execution_context::allocator<void>-{-public:-  /// @c void as no objects can be allocated through a proto-allocator.-  typedef void value_type;--  /// Rebinds an allocator to another value type.-  template <typename U>-  struct rebind-  {-    /// Specifies the type of the rebound allocator.-    typedef allocator<U> other;-  };--  /// Construct an allocator that is associated with an execution context.-  explicit constexpr allocator(execution_context& e) noexcept-    : impl_(e.allocator_.ptr_)-  {-  }--  /// Construct from another @c allocator for a different value type.-  template <typename U>-  constexpr allocator(const allocator<U>& a) noexcept-    : impl_(a.impl_)-  {-  }--  /// Equality operator.-  constexpr bool operator==(const allocator& other) const noexcept-  {-    return impl_ == other.impl_;-  }--  /// Inequality operator.-  constexpr bool operator!=(const allocator& other) const noexcept-  {-    return impl_ != other.impl_;-  }--private:-  template <typename> friend class execution_context::allocator;-  allocator_impl_base* impl_;+  asio::detail::service_registry* service_registry_; };  /// Class used to uniquely identify a service.@@ -468,7 +311,7 @@   id() {} }; -/// Base class for all execution context services.+/// Base class for all io_context services. class execution_context::service   : private noncopyable {@@ -499,7 +342,7 @@   ASIO_DECL virtual void notify_fork(       execution_context::fork_event event); -  friend class detail::service_registry;+  friend class asio::detail::service_registry;   struct key   {     key() : type_info_(0), id_(0) {}@@ -509,24 +352,6 @@    execution_context& owner_;   service* next_;-  void (*destroy_)(service*);-};--/// Base class for all execution context service makers.-/**- * A service maker is called by the execution context to create services that- * need to be installed into the execution context at construction time.- */-class execution_context::service_maker-  : private noncopyable-{-public:-  /// Make services to be added to the execution context.-  virtual void make(execution_context& context) const = 0;--protected:-  /// Destructor.-  ASIO_DECL virtual ~service_maker(); };  /// Exception thrown when trying to add a duplicate service to an
link/modules/asio-standalone/asio/include/asio/executor.hpp view
@@ -2,7 +2,7 @@ // executor.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,7 +19,6 @@  #if !defined(ASIO_NO_TS_EXECUTORS) -#include <new> #include <typeinfo> #include "asio/detail/cstddef.hpp" #include "asio/detail/executor_function.hpp"@@ -37,11 +36,11 @@ { public:   /// Constructor.-  ASIO_DECL bad_executor() noexcept;+  ASIO_DECL bad_executor() ASIO_NOEXCEPT;    /// Obtain message associated with exception.   ASIO_DECL virtual const char* what() const-    noexcept;+    ASIO_NOEXCEPT_OR_NOTHROW; };  /// Polymorphic wrapper for executors.@@ -49,53 +48,36 @@ { public:   /// Default constructor.-  executor() noexcept+  executor() ASIO_NOEXCEPT     : impl_(0)   {   }    /// Construct from nullptr.-  executor(nullptr_t) noexcept+  executor(nullptr_t) ASIO_NOEXCEPT     : impl_(0)   {   }    /// Copy constructor.-  executor(const executor& other) noexcept+  executor(const executor& other) ASIO_NOEXCEPT     : impl_(other.clone())   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.-  executor(executor&& other) noexcept+  executor(executor&& other) ASIO_NOEXCEPT     : impl_(other.impl_)   {     other.impl_ = 0;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Construct a polymorphic wrapper for the specified executor.   template <typename Executor>   executor(Executor e); -  /// Construct a polymorphic executor that points to the same target as-  /// another polymorphic executor.-  executor(std::nothrow_t, const executor& other) noexcept-    : impl_(other.clone())-  {-  }--  /// Construct a polymorphic executor that moves the target from another-  /// polymorphic executor.-  executor(std::nothrow_t, executor&& other) noexcept-    : impl_(other.impl_)-  {-    other.impl_ = 0;-  }--  /// Construct a polymorphic wrapper for the specified executor.-  template <typename Executor>-  executor(std::nothrow_t, Executor e) noexcept;-   /// Allocator-aware constructor to create a polymorphic wrapper for the   /// specified executor.   template <typename Executor, typename Allocator>@@ -108,24 +90,26 @@   }    /// Assignment operator.-  executor& operator=(const executor& other) noexcept+  executor& operator=(const executor& other) ASIO_NOEXCEPT   {     destroy();     impl_ = other.clone();     return *this;   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   // Move assignment operator.-  executor& operator=(executor&& other) noexcept+  executor& operator=(executor&& other) ASIO_NOEXCEPT   {     destroy();     impl_ = other.impl_;     other.impl_ = 0;     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Assignment operator for nullptr_t.-  executor& operator=(nullptr_t) noexcept+  executor& operator=(nullptr_t) ASIO_NOEXCEPT   {     destroy();     impl_ = 0;@@ -135,9 +119,9 @@   /// Assignment operator to create a polymorphic wrapper for the specified   /// executor.   template <typename Executor>-  executor& operator=(Executor&& e) noexcept+  executor& operator=(ASIO_MOVE_ARG(Executor) e) ASIO_NOEXCEPT   {-    executor tmp(static_cast<Executor&&>(e));+    executor tmp(ASIO_MOVE_CAST(Executor)(e));     destroy();     impl_ = tmp.impl_;     tmp.impl_ = 0;@@ -145,19 +129,19 @@   }    /// Obtain the underlying execution context.-  execution_context& context() const noexcept+  execution_context& context() const ASIO_NOEXCEPT   {     return get_impl()->context();   }    /// Inform the executor that it has some outstanding work to do.-  void on_work_started() const noexcept+  void on_work_started() const ASIO_NOEXCEPT   {     get_impl()->on_work_started();   }    /// Inform the executor that some work is no longer outstanding.-  void on_work_finished() const noexcept+  void on_work_finished() const ASIO_NOEXCEPT   {     get_impl()->on_work_finished();   }@@ -176,7 +160,7 @@    * internal storage needed for function invocation.    */   template <typename Function, typename Allocator>-  void dispatch(Function&& f, const Allocator& a) const;+  void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;    /// Request the executor to invoke the given function object.   /**@@ -192,7 +176,7 @@    * internal storage needed for function invocation.    */   template <typename Function, typename Allocator>-  void post(Function&& f, const Allocator& a) const;+  void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;    /// Request the executor to invoke the given function object.   /**@@ -208,14 +192,14 @@    * internal storage needed for function invocation.    */   template <typename Function, typename Allocator>-  void defer(Function&& f, const Allocator& a) const;+  void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const;    struct unspecified_bool_type_t {};   typedef void (*unspecified_bool_type)(unspecified_bool_type_t);   static void unspecified_bool_true(unspecified_bool_type_t) {}    /// Operator to test if the executor contains a valid target.-  operator unspecified_bool_type() const noexcept+  operator unspecified_bool_type() const ASIO_NOEXCEPT   {     return impl_ ? &executor::unspecified_bool_true : 0;   }@@ -226,12 +210,12 @@    * otherwise, <tt>typeid(void)</tt>.    */ #if !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)-  const std::type_info& target_type() const noexcept+  const std::type_info& target_type() const ASIO_NOEXCEPT   {     return impl_ ? impl_->target_type() : typeid(void);   } #else // !defined(ASIO_NO_TYPEID) || defined(GENERATING_DOCUMENTATION)-  const void* target_type() const noexcept+  const void* target_type() const ASIO_NOEXCEPT   {     return impl_ ? impl_->target_type() : 0;   }@@ -243,7 +227,7 @@    * executor target; otherwise, a null pointer.    */   template <typename Executor>-  Executor* target() noexcept;+  Executor* target() ASIO_NOEXCEPT;    /// Obtain a pointer to the target executor object.   /**@@ -251,11 +235,11 @@    * executor target; otherwise, a null pointer.    */   template <typename Executor>-  const Executor* target() const noexcept;+  const Executor* target() const ASIO_NOEXCEPT;    /// Compare two executors for equality.   friend bool operator==(const executor& a,-      const executor& b) noexcept+      const executor& b) ASIO_NOEXCEPT   {     if (a.impl_ == b.impl_)       return true;@@ -266,7 +250,7 @@    /// Compare two executors for inequality.   friend bool operator!=(const executor& a,-      const executor& b) noexcept+      const executor& b) ASIO_NOEXCEPT   {     return !(a == b);   }@@ -297,18 +281,18 @@   class impl_base   {   public:-    virtual impl_base* clone() const noexcept = 0;-    virtual void destroy() noexcept = 0;-    virtual execution_context& context() noexcept = 0;-    virtual void on_work_started() noexcept = 0;-    virtual void on_work_finished() noexcept = 0;-    virtual void dispatch(function&&) = 0;-    virtual void post(function&&) = 0;-    virtual void defer(function&&) = 0;-    virtual type_id_result_type target_type() const noexcept = 0;-    virtual void* target() noexcept = 0;-    virtual const void* target() const noexcept = 0;-    virtual bool equals(const impl_base* e) const noexcept = 0;+    virtual impl_base* clone() const ASIO_NOEXCEPT = 0;+    virtual void destroy() ASIO_NOEXCEPT = 0;+    virtual execution_context& context() ASIO_NOEXCEPT = 0;+    virtual void on_work_started() ASIO_NOEXCEPT = 0;+    virtual void on_work_finished() ASIO_NOEXCEPT = 0;+    virtual void dispatch(ASIO_MOVE_ARG(function)) = 0;+    virtual void post(ASIO_MOVE_ARG(function)) = 0;+    virtual void defer(ASIO_MOVE_ARG(function)) = 0;+    virtual type_id_result_type target_type() const ASIO_NOEXCEPT = 0;+    virtual void* target() ASIO_NOEXCEPT = 0;+    virtual const void* target() const ASIO_NOEXCEPT = 0;+    virtual bool equals(const impl_base* e) const ASIO_NOEXCEPT = 0;    protected:     impl_base(bool fast_dispatch) : fast_dispatch_(fast_dispatch) {}@@ -331,13 +315,13 @@   }    // Helper function to clone another implementation.-  impl_base* clone() const noexcept+  impl_base* clone() const ASIO_NOEXCEPT   {     return impl_ ? impl_->clone() : 0;   }    // Helper function to destroy an implementation.-  void destroy() noexcept+  void destroy() ASIO_NOEXCEPT   {     if (impl_)       impl_->destroy();
link/modules/asio-standalone/asio/include/asio/executor_work_guard.hpp view
@@ -2,7 +2,7 @@ // executor_work_guard.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -49,13 +49,13 @@   /**    * Stores a copy of @c e and calls <tt>on_work_started()</tt> on it.    */-  explicit executor_work_guard(const executor_type& e) noexcept;+  explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT;    /// Copy constructor.-  executor_work_guard(const executor_work_guard& other) noexcept;+  executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT;    /// Move constructor.-  executor_work_guard(executor_work_guard&& other) noexcept;+  executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT;    /// Destructor.   /**@@ -65,17 +65,17 @@   ~executor_work_guard();    /// Obtain the associated executor.-  executor_type get_executor() const noexcept;+  executor_type get_executor() const ASIO_NOEXCEPT;    /// Whether the executor_work_guard object owns some outstanding work.-  bool owns_work() const noexcept;+  bool owns_work() const ASIO_NOEXCEPT;    /// Indicate that the work is no longer outstanding.   /**    * Unless the object has already been reset, or is in a moved-from state,    * calls <tt>on_work_finished()</tt> on the stored executor.    */-  void reset() noexcept;+  void reset() ASIO_NOEXCEPT; };  #endif // defined(GENERATING_DOCUMENTATION)@@ -86,21 +86,21 @@  template <typename Executor> class executor_work_guard<Executor,-    enable_if_t<+    typename enable_if<       is_executor<Executor>::value-    >>+    >::type> { public:   typedef Executor executor_type; -  explicit executor_work_guard(const executor_type& e) noexcept+  explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT     : executor_(e),       owns_(true)   {     executor_.on_work_started();   } -  executor_work_guard(const executor_work_guard& other) noexcept+  executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT     : executor_(other.executor_),       owns_(other.owns_)   {@@ -108,12 +108,14 @@       executor_.on_work_started();   } -  executor_work_guard(executor_work_guard&& other) noexcept-    : executor_(static_cast<Executor&&>(other.executor_)),+#if defined(ASIO_HAS_MOVE)+  executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)),       owns_(other.owns_)   {     other.owns_ = false;   }+#endif // defined(ASIO_HAS_MOVE)    ~executor_work_guard()   {@@ -121,17 +123,17 @@       executor_.on_work_finished();   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return executor_;   } -  bool owns_work() const noexcept+  bool owns_work() const ASIO_NOEXCEPT   {     return owns_;   } -  void reset() noexcept+  void reset() ASIO_NOEXCEPT   {     if (owns_)     {@@ -152,17 +154,17 @@  template <typename Executor> class executor_work_guard<Executor,-    enable_if_t<+    typename enable_if<       !is_executor<Executor>::value-    >,-    enable_if_t<+    >::type,+    typename enable_if<       execution::is_executor<Executor>::value-    >>+    >::type> { public:   typedef Executor executor_type; -  explicit executor_work_guard(const executor_type& e) noexcept+  explicit executor_work_guard(const executor_type& e) ASIO_NOEXCEPT     : executor_(e),       owns_(true)   {@@ -170,7 +172,7 @@           execution::outstanding_work.tracked));   } -  executor_work_guard(const executor_work_guard& other) noexcept+  executor_work_guard(const executor_work_guard& other) ASIO_NOEXCEPT     : executor_(other.executor_),       owns_(other.owns_)   {@@ -181,19 +183,21 @@     }   } -  executor_work_guard(executor_work_guard&& other) noexcept-    : executor_(static_cast<Executor&&>(other.executor_)),+#if defined(ASIO_HAS_MOVE)+  executor_work_guard(executor_work_guard&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)),       owns_(other.owns_)   {     if (owns_)     {       new (&work_) work_type(-          static_cast<work_type&&>(+          ASIO_MOVE_CAST(work_type)(             *static_cast<work_type*>(               static_cast<void*>(&other.work_))));       other.owns_ = false;     }   }+#endif //  defined(ASIO_HAS_MOVE)    ~executor_work_guard()   {@@ -201,17 +205,17 @@       static_cast<work_type*>(static_cast<void*>(&work_))->~work_type();   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return executor_;   } -  bool owns_work() const noexcept+  bool owns_work() const ASIO_NOEXCEPT   {     return owns_;   } -  void reset() noexcept+  void reset() ASIO_NOEXCEPT   {     if (owns_)     {@@ -224,15 +228,16 @@   // Disallow assignment.   executor_work_guard& operator=(const executor_work_guard&); -  typedef decay_t<-      prefer_result_t<+  typedef typename decay<+      typename prefer_result<         const executor_type&,         execution::outstanding_work_t::tracked_t-      >-    > work_type;+      >::type+    >::type work_type;    executor_type executor_;-  aligned_storage_t<sizeof(work_type), alignment_of<work_type>::value> work_;+  typename aligned_storage<sizeof(work_type),+      alignment_of<work_type>::value>::type work_;   bool owns_; }; @@ -247,9 +252,9 @@ template <typename Executor> ASIO_NODISCARD inline executor_work_guard<Executor> make_work_guard(const Executor& ex,-    constraint_t<+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)+    >::type = 0) {   return executor_work_guard<Executor>(ex); }@@ -265,9 +270,9 @@ ASIO_NODISCARD inline executor_work_guard<typename ExecutionContext::executor_type> make_work_guard(ExecutionContext& ctx,-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)+    >::type = 0) {   return executor_work_guard<typename ExecutionContext::executor_type>(       ctx.get_executor());@@ -284,15 +289,15 @@ template <typename T> ASIO_NODISCARD inline executor_work_guard<-    typename constraint_t<+    typename constraint<       !is_executor<T>::value         && !execution::is_executor<T>::value         && !is_convertible<T&, execution_context&>::value,       associated_executor<T>-    >::type>+    >::type::type> make_work_guard(const T& t) {-  return executor_work_guard<associated_executor_t<T>>(+  return executor_work_guard<typename associated_executor<T>::type>(       associated_executor<T>::get(t)); } @@ -310,13 +315,13 @@  */ template <typename T, typename Executor> ASIO_NODISCARD inline-executor_work_guard<associated_executor_t<T, Executor>>+executor_work_guard<typename associated_executor<T, Executor>::type> make_work_guard(const T& t, const Executor& ex,-    constraint_t<+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)+    >::type = 0) {-  return executor_work_guard<associated_executor_t<T, Executor>>(+  return executor_work_guard<typename associated_executor<T, Executor>::type>(       associated_executor<T, Executor>::get(t, ex)); } @@ -333,24 +338,24 @@  * ctx.get_executor())</tt>.  */ template <typename T, typename ExecutionContext>-ASIO_NODISCARD inline executor_work_guard<-  associated_executor_t<T, typename ExecutionContext::executor_type>>+ASIO_NODISCARD inline executor_work_guard<typename associated_executor<T,+  typename ExecutionContext::executor_type>::type> make_work_guard(const T& t, ExecutionContext& ctx,-    constraint_t<+    typename constraint<       !is_executor<T>::value-    > = 0,-    constraint_t<+    >::type = 0,+    typename constraint<       !execution::is_executor<T>::value-    > = 0,-    constraint_t<+    >::type = 0,+    typename constraint<       !is_convertible<T&, execution_context&>::value-    > = 0,-    constraint_t<+    >::type = 0,+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)+    >::type = 0) {-  return executor_work_guard<-    associated_executor_t<T, typename ExecutionContext::executor_type>>(+  return executor_work_guard<typename associated_executor<T,+    typename ExecutionContext::executor_type>::type>(       associated_executor<T, typename ExecutionContext::executor_type>::get(         t, ctx.get_executor())); }
+ link/modules/asio-standalone/asio/include/asio/experimental/append.hpp view
@@ -0,0 +1,36 @@+//+// experimental/append.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXPERIMENTAL_APPEND_HPP+#define ASIO_EXPERIMENTAL_APPEND_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/append.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {++#if !defined(ASIO_NO_DEPRECATED)+using asio::append_t;+using asio::append;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_APPEND_HPP
link/modules/asio-standalone/asio/include/asio/experimental/as_single.hpp view
@@ -2,7 +2,7 @@ // experimental/as_single.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -47,18 +47,18 @@    * token is itself defaulted as an argument to allow it to capture a source    * location.    */-  constexpr as_single_t(+  ASIO_CONSTEXPR as_single_t(       default_constructor_tag = default_constructor_tag(),       CompletionToken token = CompletionToken())-    : token_(static_cast<CompletionToken&&>(token))+    : token_(ASIO_MOVE_CAST(CompletionToken)(token))   {   }    /// Constructor.   template <typename T>-  constexpr explicit as_single_t(-      T&& completion_token)-    : token_(static_cast<T&&>(completion_token))+  ASIO_CONSTEXPR explicit as_single_t(+      ASIO_MOVE_ARG(T) completion_token)+    : token_(ASIO_MOVE_CAST(T)(completion_token))   {   } @@ -71,7 +71,7 @@     typedef as_single_t default_completion_token_type;      /// Construct the adapted executor from the inner executor type.-    executor_with_default(const InnerExecutor& ex) noexcept+    executor_with_default(const InnerExecutor& ex) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -80,9 +80,9 @@     /// that to construct the adapted executor.     template <typename OtherExecutor>     executor_with_default(const OtherExecutor& ex,-        constraint_t<+        typename constraint<           is_convertible<OtherExecutor, InnerExecutor>::value-        > = 0) noexcept+        >::type = 0) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -90,21 +90,25 @@    /// Type alias to adapt an I/O object to use @c as_single_t as its   /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)   template <typename T>   using as_default_on_t = typename T::template rebind_executor<-      executor_with_default<typename T::executor_type>>::other;+      executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)    /// Function helper to adapt an I/O object to use @c as_single_t as its   /// default completion token type.   template <typename T>-  static typename decay_t<T>::template rebind_executor<-      executor_with_default<typename decay_t<T>::executor_type>+  static typename decay<T>::type::template rebind_executor<+      executor_with_default<typename decay<T>::type::executor_type>     >::other-  as_default_on(T&& object)+  as_default_on(ASIO_MOVE_ARG(T) object)   {-    return typename decay_t<T>::template rebind_executor<-        executor_with_default<typename decay_t<T>::executor_type>-      >::other(static_cast<T&&>(object));+    return typename decay<T>::type::template rebind_executor<+        executor_with_default<typename decay<T>::type::executor_type>+      >::other(ASIO_MOVE_CAST(T)(object));   }  //private:@@ -115,11 +119,11 @@ /// arguments should be combined into a single argument. template <typename CompletionToken> ASIO_NODISCARD inline-constexpr as_single_t<decay_t<CompletionToken>>-as_single(CompletionToken&& completion_token)+ASIO_CONSTEXPR as_single_t<typename decay<CompletionToken>::type>+as_single(ASIO_MOVE_ARG(CompletionToken) completion_token) {-  return as_single_t<decay_t<CompletionToken>>(-      static_cast<CompletionToken&&>(completion_token));+  return as_single_t<typename decay<CompletionToken>::type>(+      ASIO_MOVE_CAST(CompletionToken)(completion_token)); }  } // namespace experimental
+ link/modules/asio-standalone/asio/include/asio/experimental/as_tuple.hpp view
@@ -0,0 +1,36 @@+//+// experimental/as_tuple.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXPERIMENTAL_AS_TUPLE_HPP+#define ASIO_EXPERIMENTAL_AS_TUPLE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/as_tuple.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {++#if !defined(ASIO_NO_DEPRECATED)+using asio::as_tuple_t;+using asio::as_tuple;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_AS_TUPLE_HPP
link/modules/asio-standalone/asio/include/asio/experimental/awaitable_operators.hpp view
@@ -2,7 +2,7 @@ // experimental/awaitable_operators.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,8 +22,8 @@ #include <variant> #include "asio/awaitable.hpp" #include "asio/co_spawn.hpp"-#include "asio/deferred.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/experimental/deferred.hpp" #include "asio/experimental/parallel_group.hpp" #include "asio/multiple_exceptions.hpp" #include "asio/this_coro.hpp"@@ -37,28 +37,28 @@  template <typename T, typename Executor> awaitable<T, Executor> awaitable_wrap(awaitable<T, Executor> a,-    constraint_t<is_constructible<T>::value>* = 0)+    typename constraint<is_constructible<T>::value>::type* = 0) {   return a; }  template <typename T, typename Executor> awaitable<std::optional<T>, Executor> awaitable_wrap(awaitable<T, Executor> a,-    constraint_t<!is_constructible<T>::value>* = 0)+    typename constraint<!is_constructible<T>::value>::type* = 0) {   co_return std::optional<T>(co_await std::move(a)); }  template <typename T>-T& awaitable_unwrap(conditional_t<true, T, void>& r,-    constraint_t<is_constructible<T>::value>* = 0)+T& awaitable_unwrap(typename conditional<true, T, void>::type& r,+    typename constraint<is_constructible<T>::value>::type* = 0) {   return r; }  template <typename T>-T& awaitable_unwrap(std::optional<conditional_t<true, T, void>>& r,-    constraint_t<!is_constructible<T>::value>* = 0)+T& awaitable_unwrap(std::optional<typename conditional<true, T, void>::type>& r,+    typename constraint<!is_constructible<T>::value>::type* = 0) {   return *r; }
link/modules/asio-standalone/asio/include/asio/experimental/basic_channel.hpp view
@@ -2,7 +2,7 @@ // experimental/basic_channel.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -110,9 +110,8 @@    template <typename... PayloadSignatures,       ASIO_COMPLETION_TOKEN_FOR(PayloadSignatures...) CompletionToken>-  auto do_async_receive(-      asio::detail::completion_payload<PayloadSignatures...>*,-      CompletionToken&& token)+  auto do_async_receive(detail::channel_payload<PayloadSignatures...>*,+      ASIO_MOVE_ARG(CompletionToken) token)     -> decltype(         async_initiate<CompletionToken, PayloadSignatures...>(           declval<initiate_async_receive>(), token))@@ -168,10 +167,10 @@    */   template <typename ExecutionContext>   basic_channel(ExecutionContext& context, std::size_t max_buffer_size = 0,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : service_(&asio::use_service<service_type>(context)),       impl_(),       executor_(context.get_executor())@@ -179,6 +178,7 @@     service_->construct(impl_, max_buffer_size);   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_channel from another.   /**    * This constructor moves a channel from one object to another.@@ -236,13 +236,13 @@   template <typename Executor1>   basic_channel(       basic_channel<Executor1, Traits, Signatures...>&& other,-      constraint_t<+      typename constraint<           is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : service_(other.service_),       executor_(other.executor_)   {-    service_->move_construct(impl_, other.impl_);+    service_->move_construct(impl_, *other.service_, other.impl_);   }    /// Move-assign a basic_channel from another.@@ -259,10 +259,10 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_channel&-  > operator=(basic_channel<Executor1, Traits, Signatures...>&& other)+  >::type operator=(basic_channel<Executor1, Traits, Signatures...>&& other)   {     if (this != &other)     {@@ -273,6 +273,7 @@     }     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destructor.   ~basic_channel()@@ -281,19 +282,19 @@   }    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return executor_;   }    /// Get the capacity of the channel's buffer.-  std::size_t capacity() noexcept+  std::size_t capacity() ASIO_NOEXCEPT   {     return service_->capacity(impl_);   }    /// Determine whether the channel is open.-  bool is_open() const noexcept+  bool is_open() const ASIO_NOEXCEPT   {     return service_->is_open(impl_);   }@@ -322,7 +323,7 @@   }    /// Determine whether a message can be received without blocking.-  bool ready() const noexcept+  bool ready() const ASIO_NOEXCEPT   {     return service_->ready(impl_);   }@@ -336,38 +337,14 @@    * @returns @c true on success, @c false on failure.    */   template <typename... Args>-  bool try_send(Args&&... args);--  /// Try to send a message without blocking, using dispatch semantics to call-  /// the receive operation's completion handler.-  /**-   * Fails if the buffer is full and there are no waiting receive operations.-   *-   * The receive operation's completion handler may be called from inside this-   * function.-   *-   * @returns @c true on success, @c false on failure.-   */-  template <typename... Args>-  bool try_send_via_dispatch(Args&&... args);+  bool try_send(ASIO_MOVE_ARG(Args)... args);    /// Try to send a number of messages without blocking.   /**    * @returns The number of messages that were sent.    */   template <typename... Args>-  std::size_t try_send_n(std::size_t count, Args&&... args);--  /// Try to send a number of messages without blocking, using dispatch-  /// semantics to call the receive operations' completion handlers.-  /**-   * The receive operations' completion handlers may be called from inside this-   * function.-   *-   * @returns The number of messages that were sent.-   */-  template <typename... Args>-  std::size_t try_send_n_via_dispatch(std::size_t count, Args&&... args);+  std::size_t try_send_n(std::size_t count, ASIO_MOVE_ARG(Args)... args);    /// Asynchronously send a message.   /**@@ -377,8 +354,8 @@   template <typename... Args,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))         CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>-  auto async_send(Args&&... args,-      CompletionToken&& token);+  auto async_send(ASIO_MOVE_ARG(Args)... args,+      ASIO_MOVE_ARG(CompletionToken) token);  #endif // defined(GENERATING_DOCUMENTATION) @@ -389,9 +366,9 @@    * @returns @c true on success, @c false on failure.    */   template <typename Handler>-  bool try_receive(Handler&& handler)+  bool try_receive(ASIO_MOVE_ARG(Handler) handler)   {-    return service_->try_receive(impl_, static_cast<Handler&&>(handler));+    return service_->try_receive(impl_, ASIO_MOVE_CAST(Handler)(handler));   }    /// Asynchronously receive a message.@@ -403,22 +380,22 @@   template <typename CompletionToken       ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>   auto async_receive(-      CompletionToken&& token+      ASIO_MOVE_ARG(CompletionToken) token         ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) #if !defined(GENERATING_DOCUMENTATION)     -> decltype(         this->do_async_receive(static_cast<payload_type*>(0),-          static_cast<CompletionToken&&>(token)))+          ASIO_MOVE_CAST(CompletionToken)(token))) #endif // !defined(GENERATING_DOCUMENTATION)   {     return this->do_async_receive(static_cast<payload_type*>(0),-        static_cast<CompletionToken&&>(token));+        ASIO_MOVE_CAST(CompletionToken)(token));   }  private:   // Disallow copying and assignment.-  basic_channel(const basic_channel&) = delete;-  basic_channel& operator=(const basic_channel&) = delete;+  basic_channel(const basic_channel&) ASIO_DELETED;+  basic_channel& operator=(const basic_channel&) ASIO_DELETED;    template <typename, typename, typename...>   friend class detail::channel_send_functions;@@ -426,7 +403,7 @@   // Helper function to get an executor's context.   template <typename T>   static execution_context& get_context(const T& t,-      enable_if_t<execution::is_executor<T>::value>* = 0)+      typename enable_if<execution::is_executor<T>::value>::type* = 0)   {     return asio::query(t, execution::context);   }@@ -434,7 +411,7 @@   // Helper function to get an executor's context.   template <typename T>   static execution_context& get_context(const T& t,-      enable_if_t<!execution::is_executor<T>::value>* = 0)+      typename enable_if<!execution::is_executor<T>::value>::type* = 0)   {     return t.context();   }@@ -449,18 +426,18 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename SendHandler>-    void operator()(SendHandler&& handler,-        payload_type&& payload) const+    void operator()(ASIO_MOVE_ARG(SendHandler) handler,+        ASIO_MOVE_ARG(payload_type) payload) const     {       asio::detail::non_const_lvalue<SendHandler> handler2(handler);       self_->service_->async_send(self_->impl_,-          static_cast<payload_type&&>(payload),+          ASIO_MOVE_CAST(payload_type)(payload),           handler2.value, self_->get_executor());     } @@ -478,13 +455,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReceiveHandler>-    void operator()(ReceiveHandler&& handler) const+    void operator()(ASIO_MOVE_ARG(ReceiveHandler) handler) const     {       asio::detail::non_const_lvalue<ReceiveHandler> handler2(handler);       self_->service_->async_receive(self_->impl_,
link/modules/asio-standalone/asio/include/asio/experimental/basic_concurrent_channel.hpp view
@@ -2,7 +2,7 @@ // experimental/basic_concurrent_channel.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -110,9 +110,8 @@    template <typename... PayloadSignatures,       ASIO_COMPLETION_TOKEN_FOR(PayloadSignatures...) CompletionToken>-  auto do_async_receive(-      asio::detail::completion_payload<PayloadSignatures...>*,-      CompletionToken&& token)+  auto do_async_receive(detail::channel_payload<PayloadSignatures...>*,+      ASIO_MOVE_ARG(CompletionToken) token)     -> decltype(         async_initiate<CompletionToken, PayloadSignatures...>(           declval<initiate_async_receive>(), token))@@ -170,10 +169,10 @@   template <typename ExecutionContext>   basic_concurrent_channel(ExecutionContext& context,       std::size_t max_buffer_size = 0,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : service_(&asio::use_service<service_type>(context)),       impl_(),       executor_(context.get_executor())@@ -181,6 +180,7 @@     service_->construct(impl_, max_buffer_size);   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_concurrent_channel from another.   /**    * This constructor moves a channel from one object to another.@@ -242,13 +242,13 @@   template <typename Executor1>   basic_concurrent_channel(       basic_concurrent_channel<Executor1, Traits, Signatures...>&& other,-      constraint_t<+      typename constraint<           is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : service_(other.service_),       executor_(other.executor_)   {-    service_->move_construct(impl_, other.impl_);+    service_->move_construct(impl_, *other.service_, other.impl_);   }    /// Move-assign a basic_concurrent_channel from another.@@ -265,10 +265,10 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_concurrent_channel&-  > operator=(+  >::type operator=(       basic_concurrent_channel<Executor1, Traits, Signatures...>&& other)   {     if (this != &other)@@ -280,6 +280,7 @@     }     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destructor.   ~basic_concurrent_channel()@@ -288,19 +289,19 @@   }    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return executor_;   }    /// Get the capacity of the channel's buffer.-  std::size_t capacity() noexcept+  std::size_t capacity() ASIO_NOEXCEPT   {     return service_->capacity(impl_);   }    /// Determine whether the channel is open.-  bool is_open() const noexcept+  bool is_open() const ASIO_NOEXCEPT   {     return service_->is_open(impl_);   }@@ -329,7 +330,7 @@   }    /// Determine whether a message can be received without blocking.-  bool ready() const noexcept+  bool ready() const ASIO_NOEXCEPT   {     return service_->ready(impl_);   }@@ -343,45 +344,21 @@    * @returns @c true on success, @c false on failure.    */   template <typename... Args>-  bool try_send(Args&&... args);--  /// Try to send a message without blocking, using dispatch semantics to call-  /// the receive operation's completion handler.-  /**-   * Fails if the buffer is full and there are no waiting receive operations.-   *-   * The receive operation's completion handler may be called from inside this-   * function.-   *-   * @returns @c true on success, @c false on failure.-   */-  template <typename... Args>-  bool try_send_via_dispatch(Args&&... args);+  bool try_send(ASIO_MOVE_ARG(Args)... args);    /// Try to send a number of messages without blocking.   /**    * @returns The number of messages that were sent.    */   template <typename... Args>-  std::size_t try_send_n(std::size_t count, Args&&... args);--  /// Try to send a number of messages without blocking, using dispatch-  /// semantics to call the receive operations' completion handlers.-  /**-   * The receive operations' completion handlers may be called from inside this-   * function.-   *-   * @returns The number of messages that were sent.-   */-  template <typename... Args>-  std::size_t try_send_n_via_dispatch(std::size_t count, Args&&... args);+  std::size_t try_send_n(std::size_t count, ASIO_MOVE_ARG(Args)... args);    /// Asynchronously send a message.   template <typename... Args,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))         CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>-  auto async_send(Args&&... args,-      CompletionToken&& token);+  auto async_send(ASIO_MOVE_ARG(Args)... args,+      ASIO_MOVE_ARG(CompletionToken) token);  #endif // defined(GENERATING_DOCUMENTATION) @@ -392,33 +369,33 @@    * @returns @c true on success, @c false on failure.    */   template <typename Handler>-  bool try_receive(Handler&& handler)+  bool try_receive(ASIO_MOVE_ARG(Handler) handler)   {-    return service_->try_receive(impl_, static_cast<Handler&&>(handler));+    return service_->try_receive(impl_, ASIO_MOVE_CAST(Handler)(handler));   }    /// Asynchronously receive a message.   template <typename CompletionToken       ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>   auto async_receive(-      CompletionToken&& token+      ASIO_MOVE_ARG(CompletionToken) token         ASIO_DEFAULT_COMPLETION_TOKEN(Executor)) #if !defined(GENERATING_DOCUMENTATION)     -> decltype(         this->do_async_receive(static_cast<payload_type*>(0),-          static_cast<CompletionToken&&>(token)))+          ASIO_MOVE_CAST(CompletionToken)(token))) #endif // !defined(GENERATING_DOCUMENTATION)   {     return this->do_async_receive(static_cast<payload_type*>(0),-        static_cast<CompletionToken&&>(token));+        ASIO_MOVE_CAST(CompletionToken)(token));   }  private:   // Disallow copying and assignment.   basic_concurrent_channel(-      const basic_concurrent_channel&) = delete;+      const basic_concurrent_channel&) ASIO_DELETED;   basic_concurrent_channel& operator=(-      const basic_concurrent_channel&) = delete;+      const basic_concurrent_channel&) ASIO_DELETED;    template <typename, typename, typename...>   friend class detail::channel_send_functions;@@ -426,7 +403,7 @@   // Helper function to get an executor's context.   template <typename T>   static execution_context& get_context(const T& t,-      enable_if_t<execution::is_executor<T>::value>* = 0)+      typename enable_if<execution::is_executor<T>::value>::type* = 0)   {     return asio::query(t, execution::context);   }@@ -434,7 +411,7 @@   // Helper function to get an executor's context.   template <typename T>   static execution_context& get_context(const T& t,-      enable_if_t<!execution::is_executor<T>::value>* = 0)+      typename enable_if<!execution::is_executor<T>::value>::type* = 0)   {     return t.context();   }@@ -449,18 +426,18 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename SendHandler>-    void operator()(SendHandler&& handler,-        payload_type&& payload) const+    void operator()(ASIO_MOVE_ARG(SendHandler) handler,+        ASIO_MOVE_ARG(payload_type) payload) const     {       asio::detail::non_const_lvalue<SendHandler> handler2(handler);       self_->service_->async_send(self_->impl_,-          static_cast<payload_type&&>(payload),+          ASIO_MOVE_CAST(payload_type)(payload),           handler2.value, self_->get_executor());     } @@ -478,13 +455,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReceiveHandler>-    void operator()(ReceiveHandler&& handler) const+    void operator()(ASIO_MOVE_ARG(ReceiveHandler) handler) const     {       asio::detail::non_const_lvalue<ReceiveHandler> handler2(handler);       self_->service_->async_receive(self_->impl_,
link/modules/asio-standalone/asio/include/asio/experimental/cancellation_condition.hpp view
@@ -2,7 +2,7 @@ // experimental/cancellation_condition.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,8 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+#include <exception> #include "asio/cancellation_type.hpp"-#include "asio/disposition.hpp"+#include "asio/error_code.hpp" #include "asio/detail/type_traits.hpp"  #include "asio/detail/push_options.hpp"@@ -30,7 +31,8 @@ { public:   template <typename... Args>-  constexpr cancellation_type_t operator()(Args&&...) const noexcept+  ASIO_CONSTEXPR cancellation_type_t operator()(+      Args&&...) const ASIO_NOEXCEPT   {     return cancellation_type::none;   }@@ -40,14 +42,15 @@ class wait_for_one { public:-  constexpr explicit wait_for_one(+  ASIO_CONSTEXPR explicit wait_for_one(       cancellation_type_t cancel_type = cancellation_type::all)     : cancel_type_(cancel_type)   {   }    template <typename... Args>-  constexpr cancellation_type_t operator()(Args&&...) const noexcept+  ASIO_CONSTEXPR cancellation_type_t operator()(+      Args&&...) const ASIO_NOEXCEPT   {     return cancel_type_;   }@@ -64,30 +67,36 @@ class wait_for_one_success { public:-  constexpr explicit wait_for_one_success(+  ASIO_CONSTEXPR explicit wait_for_one_success(       cancellation_type_t cancel_type = cancellation_type::all)     : cancel_type_(cancel_type)   {   } -  constexpr cancellation_type_t-  operator()() const noexcept+  ASIO_CONSTEXPR cancellation_type_t+  operator()() const ASIO_NOEXCEPT   {     return cancel_type_;   }    template <typename E, typename... Args>-  constexpr constraint_t<!is_disposition<E>::value, cancellation_type_t>-  operator()(const E&, Args&&...) const noexcept+  ASIO_CONSTEXPR typename constraint<+    !is_same<typename decay<E>::type, asio::error_code>::value+      && !is_same<typename decay<E>::type, std::exception_ptr>::value,+    cancellation_type_t+  >::type operator()(const E&, Args&&...) const ASIO_NOEXCEPT   {     return cancel_type_;   }    template <typename E, typename... Args>-  constexpr constraint_t<is_disposition<E>::value, cancellation_type_t>-  operator()(const E& e, Args&&...) const noexcept+  ASIO_CONSTEXPR typename constraint<+      is_same<typename decay<E>::type, asio::error_code>::value+        || is_same<typename decay<E>::type, std::exception_ptr>::value,+      cancellation_type_t+  >::type operator()(const E& e, Args&&...) const ASIO_NOEXCEPT   {-    return e != no_error ? cancellation_type::none : cancel_type_;+    return !!e ? cancellation_type::none : cancel_type_;   }  private:@@ -102,29 +111,36 @@ class wait_for_one_error { public:-  constexpr explicit wait_for_one_error(+  ASIO_CONSTEXPR explicit wait_for_one_error(       cancellation_type_t cancel_type = cancellation_type::all)     : cancel_type_(cancel_type)   {   } -  constexpr cancellation_type_t operator()() const noexcept+  ASIO_CONSTEXPR cancellation_type_t+  operator()() const ASIO_NOEXCEPT   {     return cancellation_type::none;   }    template <typename E, typename... Args>-  constexpr constraint_t<!is_disposition<E>::value, cancellation_type_t>-  operator()(const E&, Args&&...) const noexcept+  ASIO_CONSTEXPR typename constraint<+    !is_same<typename decay<E>::type, asio::error_code>::value+      && !is_same<typename decay<E>::type, std::exception_ptr>::value,+    cancellation_type_t+  >::type operator()(const E&, Args&&...) const ASIO_NOEXCEPT   {     return cancellation_type::none;   }    template <typename E, typename... Args>-  constexpr constraint_t<is_disposition<E>::value, cancellation_type_t>-  operator()(const E& e, Args&&...) const noexcept+  ASIO_CONSTEXPR typename constraint<+      is_same<typename decay<E>::type, asio::error_code>::value+        || is_same<typename decay<E>::type, std::exception_ptr>::value,+      cancellation_type_t+  >::type operator()(const E& e, Args&&...) const ASIO_NOEXCEPT   {-    return e != no_error ? cancel_type_ : cancellation_type::none;+    return !!e ? cancel_type_ : cancellation_type::none;   }  private:
link/modules/asio-standalone/asio/include/asio/experimental/channel.hpp view
@@ -2,7 +2,7 @@ // experimental/channel.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -42,10 +42,10 @@  template <typename ExecutorOrSignature> struct channel_type<ExecutorOrSignature,-    enable_if_t<+    typename enable_if<       is_executor<ExecutorOrSignature>::value         || execution::is_executor<ExecutorOrSignature>::value-    >>+    >::type> {   template <typename... Signatures>   struct inner@@ -58,15 +58,9 @@ } // namespace detail  /// Template type alias for common use of channel.-#if defined(GENERATING_DOCUMENTATION) template <typename ExecutorOrSignature, typename... Signatures>-using channel = basic_channel<-    specified_executor_or_any_io_executor, channel_traits<>, signatures...>;-#else // defined(GENERATING_DOCUMENTATION)-template <typename ExecutorOrSignature, typename... Signatures> using channel = typename detail::channel_type<     ExecutorOrSignature>::template inner<Signatures...>::type;-#endif // defined(GENERATING_DOCUMENTATION)  } // namespace experimental } // namespace asio
link/modules/asio-standalone/asio/include/asio/experimental/channel_error.hpp view
@@ -2,7 +2,7 @@ // experimental/channel_error.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -49,6 +49,7 @@ } // namespace experimental } // namespace asio +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std {  template<> struct is_error_code_enum<@@ -58,6 +59,7 @@ };  } // namespace std+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)  namespace asio { namespace experimental {
link/modules/asio-standalone/asio/include/asio/experimental/channel_traits.hpp view
@@ -2,7 +2,7 @@ // experimental/channel_traits.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -102,7 +102,7 @@   static void invoke_receive_cancelled(F f)   {     const asio::error_code e = error::channel_cancelled;-    static_cast<F&&>(f)(e);+    ASIO_MOVE_OR_LVALUE(F)(f)(e);   }    typedef R receive_closed_signature(asio::error_code);@@ -111,7 +111,7 @@   static void invoke_receive_closed(F f)   {     const asio::error_code e = error::channel_closed;-    static_cast<F&&>(f)(e);+    ASIO_MOVE_OR_LVALUE(F)(f)(e);   } }; @@ -136,7 +136,7 @@   static void invoke_receive_cancelled(F f)   {     const asio::error_code e = error::channel_cancelled;-    static_cast<F&&>(f)(e, decay_t<Args>()...);+    ASIO_MOVE_OR_LVALUE(F)(f)(e, typename decay<Args>::type()...);   }    typedef R receive_closed_signature(asio::error_code, Args...);@@ -145,7 +145,7 @@   static void invoke_receive_closed(F f)   {     const asio::error_code e = error::channel_closed;-    static_cast<F&&>(f)(e, decay_t<Args>()...);+    ASIO_MOVE_OR_LVALUE(F)(f)(e, typename decay<Args>::type()...);   } }; @@ -170,7 +170,7 @@   static void invoke_receive_cancelled(F f)   {     const asio::error_code e = error::channel_cancelled;-    static_cast<F&&>(f)(+    ASIO_MOVE_OR_LVALUE(F)(f)(         std::make_exception_ptr(asio::system_error(e)));   } @@ -180,7 +180,7 @@   static void invoke_receive_closed(F f)   {     const asio::error_code e = error::channel_closed;-    static_cast<F&&>(f)(+    ASIO_MOVE_OR_LVALUE(F)(f)(         std::make_exception_ptr(asio::system_error(e)));   } };@@ -206,9 +206,9 @@   static void invoke_receive_cancelled(F f)   {     const asio::error_code e = error::channel_cancelled;-    static_cast<F&&>(f)(+    ASIO_MOVE_OR_LVALUE(F)(f)(         std::make_exception_ptr(asio::system_error(e)),-        decay_t<Args>()...);+        typename decay<Args>::type()...);   }    typedef R receive_closed_signature(std::exception_ptr, Args...);@@ -217,9 +217,9 @@   static void invoke_receive_closed(F f)   {     const asio::error_code e = error::channel_closed;-    static_cast<F&&>(f)(+    ASIO_MOVE_OR_LVALUE(F)(f)(         std::make_exception_ptr(asio::system_error(e)),-        decay_t<Args>()...);+        typename decay<Args>::type()...);   } }; @@ -244,7 +244,7 @@   static void invoke_receive_cancelled(F f)   {     const asio::error_code e = error::channel_cancelled;-    static_cast<F&&>(f)(e);+    ASIO_MOVE_OR_LVALUE(F)(f)(e);   }    typedef R receive_closed_signature(asio::error_code);@@ -253,7 +253,7 @@   static void invoke_receive_closed(F f)   {     const asio::error_code e = error::channel_closed;-    static_cast<F&&>(f)(e);+    ASIO_MOVE_OR_LVALUE(F)(f)(e);   } }; @@ -278,7 +278,7 @@   static void invoke_receive_cancelled(F f)   {     const asio::error_code e = error::channel_cancelled;-    static_cast<F&&>(f)(e);+    ASIO_MOVE_OR_LVALUE(F)(f)(e);   }    typedef R receive_closed_signature(asio::error_code);@@ -287,7 +287,7 @@   static void invoke_receive_closed(F f)   {     const asio::error_code e = error::channel_closed;-    static_cast<F&&>(f)(e);+    ASIO_MOVE_OR_LVALUE(F)(f)(e);   } }; 
link/modules/asio-standalone/asio/include/asio/experimental/co_composed.hpp view
@@ -2,7 +2,7 @@ // experimental/co_composed.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,18 +16,129 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include "asio/co_composed.hpp"+#include "asio/async_result.hpp"  #include "asio/detail/push_options.hpp"  namespace asio { namespace experimental { -using asio::co_composed;+/// Creates an initiation function object that may be used to launch a+/// coroutine-based composed asynchronous operation.+/**+ * The experimental::co_composed utility simplifies the implementation of+ * composed asynchronous operations by automatically adapting a coroutine to be+ * an initiation function object for use with @c async_initiate. When awaiting+ * asynchronous operations, the coroutine automatically uses a conforming+ * intermediate completion handler.+ *+ * @param implementation A function object that contains the coroutine-based+ * implementation of the composed asynchronous operation. The first argument to+ * the function object represents the state of the operation, and may be used+ * to test for cancellation. The remaining arguments are those passed to @c+ * async_initiate after the completion token.+ *+ * @param io_objects_or_executors Zero or more I/O objects or I/O executors for+ * which outstanding work must be maintained while the operation is incomplete.+ *+ * @par Per-Operation Cancellation+ * By default, per-operation cancellation is disabled for composed operations+ * that use experimental::co_composed. It must be explicitly enabled by calling+ * the state's @c reset_cancellation_state function.+ *+ * @par Examples+ * The following example illustrates manual error handling and explicit checks+ * for cancellation. The completion handler is invoked via a @c co_yield to the+ * state's @c complete function, which never returns.+ *+ * @code template <typename CompletionToken>+ * auto async_echo(tcp::socket& socket,+ *     CompletionToken&& token)+ * {+ *   return asio::async_initiate<+ *     CompletionToken, void(std::error_code)>(+ *       asio::experimental::co_composed(+ *         [](auto state, tcp::socket& socket) -> void+ *         {+ *           state.reset_cancellation_state(+ *             asio::enable_terminal_cancellation());+ *+ *           while (!state.cancelled())+ *           {+ *             char data[1024];+ *             auto [e1, n1] =+ *               co_await socket.async_read_some(+ *                 asio::buffer(data),+ *                 asio::as_tuple(asio::deferred));+ *+ *             if (e1)+ *               co_yield state.complete(e1);+ *+ *             if (!!state.cancelled())+ *               co_yield state.complete(+ *                 make_error_code(asio::error::operation_aborted));+ *+ *             auto [e2, n2] =+ *               co_await asio::async_write(socket,+ *                 asio::buffer(data, n1),+ *                 asio::as_tuple(asio::deferred));+ *+ *             if (e2)+ *               co_yield state.complete(e2);+ *           }+ *         }, socket),+ *       token, std::ref(socket));+ * } @endcode+ *+ * This next example shows exception-based error handling and implicit checks+ * for cancellation. The completion handler is invoked after returning from the+ * coroutine via @c co_return. Valid @c co_return values are specified using+ * completion signatures passed to the @c co_composed function.+ *+ * @code template <typename CompletionToken>+ * auto async_echo(tcp::socket& socket,+ *     CompletionToken&& token)+ * {+ *   return asio::async_initiate<+ *     CompletionToken, void(std::error_code)>(+ *       asio::experimental::co_composed<+ *         void(std::error_code)>(+ *           [](auto state, tcp::socket& socket) -> void+ *           {+ *             try+ *             {+ *               state.throw_if_cancelled(true);+ *               state.reset_cancellation_state(+ *                 asio::enable_terminal_cancellation());+ *+ *               for (;;)+ *               {+ *                 char data[1024];+ *                 std::size_t n = co_await socket.async_read_some(+ *                     asio::buffer(data), asio::deferred);+ *+ *                 co_await asio::async_write(socket,+ *                     asio::buffer(data, n), asio::deferred);+ *               }+ *             }+ *             catch (const std::system_error& e)+ *             {+ *               co_return {e.code()};+ *             }+ *           }, socket),+ *       token, std::ref(socket));+ * } @endcode+ */+template <completion_signature... Signatures,+    typename Implementation, typename... IoObjectsOrExecutors>+auto co_composed(Implementation&& implementation,+    IoObjectsOrExecutors&&... io_objects_or_executors);  } // namespace experimental } // namespace asio  #include "asio/detail/pop_options.hpp"++#include "asio/experimental/impl/co_composed.hpp"  #endif // ASIO_EXPERIMENTAL_CO_COMPOSED_HPP
link/modules/asio-standalone/asio/include/asio/experimental/co_spawn.hpp view
@@ -18,10 +18,10 @@ #include "asio/detail/config.hpp" #include <utility> #include "asio/compose.hpp"-#include "asio/deferred.hpp" #include "asio/detail/type_traits.hpp" #include "asio/experimental/coro.hpp"-#include "asio/prepend.hpp"+#include "asio/experimental/deferred.hpp"+#include "asio/experimental/prepend.hpp" #include "asio/redirect_error.hpp"  #include "asio/detail/push_options.hpp"
link/modules/asio-standalone/asio/include/asio/experimental/concurrent_channel.hpp view
@@ -2,7 +2,7 @@ // experimental/concurrent_channel.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -42,10 +42,10 @@  template <typename ExecutorOrSignature> struct concurrent_channel_type<ExecutorOrSignature,-    enable_if_t<+    typename enable_if<       is_executor<ExecutorOrSignature>::value         || execution::is_executor<ExecutorOrSignature>::value-    >>+    >::type> {   template <typename... Signatures>   struct inner@@ -58,15 +58,9 @@ } // namespace detail  /// Template type alias for common use of channel.-#if defined(GENERATING_DOCUMENTATION) template <typename ExecutorOrSignature, typename... Signatures>-using concurrent_channel = basic_concurrent_channel<-    specified_executor_or_any_io_executor, channel_traits<>, signatures...>;-#else // defined(GENERATING_DOCUMENTATION)-template <typename ExecutorOrSignature, typename... Signatures> using concurrent_channel = typename detail::concurrent_channel_type<     ExecutorOrSignature>::template inner<Signatures...>::type;-#endif // defined(GENERATING_DOCUMENTATION)  } // namespace experimental } // namespace asio
+ link/modules/asio-standalone/asio/include/asio/experimental/deferred.hpp view
@@ -0,0 +1,36 @@+//+// experimental/deferred.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXPERIMENTAL_DEFERRED_HPP+#define ASIO_EXPERIMENTAL_DEFERRED_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/deferred.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {++#if !defined(ASIO_NO_DEPRECATED)+using asio::deferred_t;+using asio::deferred;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_DEFERRED_HPP
+ link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_handler.hpp view
@@ -0,0 +1,80 @@+//+// experimental/detail/channel_handler.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXPERIMENTAL_DETAIL_CHANNEL_HANDLER_HPP+#define ASIO_EXPERIMENTAL_DETAIL_CHANNEL_HANDLER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/associator.hpp"+#include "asio/experimental/detail/channel_payload.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {+namespace detail {++template <typename Payload, typename Handler>+class channel_handler+{+public:+  channel_handler(ASIO_MOVE_ARG(Payload) p, Handler& h)+    : payload_(ASIO_MOVE_CAST(Payload)(p)),+      handler_(ASIO_MOVE_CAST(Handler)(h))+  {+  }++  void operator()()+  {+    payload_.receive(handler_);+  }++//private:+  Payload payload_;+  Handler handler_;+};++} // namespace detail+} // namespace experimental++template <template <typename, typename> class Associator,+    typename Payload, typename Handler, typename DefaultCandidate>+struct associator<Associator,+    experimental::detail::channel_handler<Payload, Handler>,+    DefaultCandidate>+  : Associator<Handler, DefaultCandidate>+{+  static typename Associator<Handler, DefaultCandidate>::type+  get(const experimental::detail::channel_handler<Payload, Handler>& h)+    ASIO_NOEXCEPT+  {+    return Associator<Handler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const experimental::detail::channel_handler<Payload, Handler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<Handler, DefaultCandidate>::get(h.handler_, c);+  }+};++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_DETAIL_CHANNEL_HANDLER_HPP
+ link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_message.hpp view
@@ -0,0 +1,129 @@+//+// experimental/detail/channel_message.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXPERIMENTAL_DETAIL_CHANNEL_MESSAGE_HPP+#define ASIO_EXPERIMENTAL_DETAIL_CHANNEL_MESSAGE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <tuple>+#include "asio/detail/type_traits.hpp"+#include "asio/detail/utility.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {+namespace detail {++template <typename Signature>+class channel_message;++template <typename R>+class channel_message<R()>+{+public:+  channel_message(int)+  {+  }++  template <typename Handler>+  void receive(Handler& handler)+  {+    ASIO_MOVE_OR_LVALUE(Handler)(handler)();+  }+};++template <typename R, typename Arg0>+class channel_message<R(Arg0)>+{+public:+  template <typename T0>+  channel_message(int, ASIO_MOVE_ARG(T0) t0)+    : arg0_(ASIO_MOVE_CAST(T0)(t0))+  {+  }++  template <typename Handler>+  void receive(Handler& handler)+  {+    ASIO_MOVE_OR_LVALUE(Handler)(handler)(+        ASIO_MOVE_CAST(arg0_type)(arg0_));+  }++private:+  typedef typename decay<Arg0>::type arg0_type;+  arg0_type arg0_;+};++template <typename R, typename Arg0, typename Arg1>+class channel_message<R(Arg0, Arg1)>+{+public:+  template <typename T0, typename T1>+  channel_message(int, ASIO_MOVE_ARG(T0) t0, ASIO_MOVE_ARG(T1) t1)+    : arg0_(ASIO_MOVE_CAST(T0)(t0)),+      arg1_(ASIO_MOVE_CAST(T1)(t1))+  {+  }++  template <typename Handler>+  void receive(Handler& handler)+  {+    ASIO_MOVE_OR_LVALUE(Handler)(handler)(+        ASIO_MOVE_CAST(arg0_type)(arg0_),+        ASIO_MOVE_CAST(arg1_type)(arg1_));+  }++private:+  typedef typename decay<Arg0>::type arg0_type;+  arg0_type arg0_;+  typedef typename decay<Arg1>::type arg1_type;+  arg1_type arg1_;+};++template <typename R, typename... Args>+class channel_message<R(Args...)>+{+public:+  template <typename... T>+  channel_message(int, ASIO_MOVE_ARG(T)... t)+    : args_(ASIO_MOVE_CAST(T)(t)...)+  {+  }++  template <typename Handler>+  void receive(Handler& h)+  {+    this->do_receive(h, asio::detail::index_sequence_for<Args...>());+  }++private:+  template <typename Handler, std::size_t... I>+  void do_receive(Handler& h, asio::detail::index_sequence<I...>)+  {+    ASIO_MOVE_OR_LVALUE(Handler)(h)(+        std::get<I>(ASIO_MOVE_CAST(args_type)(args_))...);+  }++  typedef std::tuple<typename decay<Args>::type...> args_type;+  args_type args_;+};++} // namespace detail+} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_DETAIL_CHANNEL_MESSAGE_HPP
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_operation.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_operation.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -39,7 +39,7 @@ class channel_operation ASIO_INHERIT_TRACKED_HANDLER { public:-  template <typename Executor, typename = void, typename = void>+  template <typename Executor, typename = void>   class handler_work_base;    template <typename Handler, typename IoExecutor, typename = void>@@ -55,10 +55,9 @@   {     destroy_op = 0,     immediate_op = 1,-    post_op = 2,-    dispatch_op = 3,-    cancel_op = 4,-    close_op = 5+    complete_op = 2,+    cancel_op = 3,+    close_op = 4   };    typedef void (*func_type)(channel_operation*, action, void*);@@ -84,96 +83,44 @@   void* cancellation_key_; }; -template <typename Executor, typename, typename>+template <typename Executor, typename> class channel_operation::handler_work_base { public:-  typedef decay_t<-      prefer_result_t<Executor,+  typedef typename decay<+      typename prefer_result<Executor,         execution::outstanding_work_t::tracked_t-      >-    > executor_type;+      >::type+    >::type executor_type;    handler_work_base(int, const Executor& ex)     : executor_(asio::prefer(ex, execution::outstanding_work.tracked))   {   } -  const executor_type& get_executor() const noexcept+  const executor_type& get_executor() const ASIO_NOEXCEPT   {     return executor_;   } -  template <typename IoExecutor, typename Function, typename Handler>-  void post(const IoExecutor& io_exec, Function& function, Handler&)-  {-    (asio::detail::initiate_post_with_executor<IoExecutor>(io_exec))(-        static_cast<Function&&>(function));-  }-   template <typename Function, typename Handler>-  void dispatch(Function& function, Handler& handler)-  {-    associated_allocator_t<Handler> allocator =-      (get_associated_allocator)(handler);--    asio::prefer(executor_,-        execution::allocator(allocator)-      ).execute(static_cast<Function&&>(function));-  }--private:-  executor_type executor_;-};--template <typename Executor>-class channel_operation::handler_work_base<Executor,-    enable_if_t<-      execution::is_executor<Executor>::value-    >,-    enable_if_t<-      can_require<Executor, execution::blocking_t::never_t>::value-    >-  >-{-public:-  typedef decay_t<-      prefer_result_t<Executor,-        execution::outstanding_work_t::tracked_t-      >-    > executor_type;--  handler_work_base(int, const Executor& ex)-    : executor_(asio::prefer(ex, execution::outstanding_work.tracked))-  {-  }--  const executor_type& get_executor() const noexcept-  {-    return executor_;-  }--  template <typename IoExecutor, typename Function, typename Handler>-  void post(const IoExecutor&, Function& function, Handler& handler)+  void post(Function& function, Handler& handler)   {-    associated_allocator_t<Handler> allocator =+    typename associated_allocator<Handler>::type allocator =       (get_associated_allocator)(handler); +#if defined(ASIO_NO_DEPRECATED)     asio::prefer(         asio::require(executor_, execution::blocking.never),         execution::allocator(allocator)-      ).execute(static_cast<Function&&>(function));-  }--  template <typename Function, typename Handler>-  void dispatch(Function& function, Handler& handler)-  {-    associated_allocator_t<Handler> allocator =-      (get_associated_allocator)(handler);--    asio::prefer(executor_,-        execution::allocator(allocator)-      ).execute(static_cast<Function&&>(function));+      ).execute(ASIO_MOVE_CAST(Function)(function));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::prefer(+          asio::require(executor_, execution::blocking.never),+          execution::allocator(allocator)),+        ASIO_MOVE_CAST(Function)(function));+#endif // defined(ASIO_NO_DEPRECATED)   }  private:@@ -184,10 +131,9 @@  template <typename Executor> class channel_operation::handler_work_base<Executor,-    enable_if_t<+    typename enable_if<       !execution::is_executor<Executor>::value-    >-  >+    >::type> { public:   typedef Executor executor_type;@@ -197,29 +143,19 @@   {   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return work_.get_executor();   } -  template <typename IoExecutor, typename Function, typename Handler>-  void post(const IoExecutor&, Function& function, Handler& handler)-  {-    associated_allocator_t<Handler> allocator =-      (get_associated_allocator)(handler);--    work_.get_executor().post(-        static_cast<Function&&>(function), allocator);-  }-   template <typename Function, typename Handler>-  void dispatch(Function& function, Handler& handler)+  void post(Function& function, Handler& handler)   {-    associated_allocator_t<Handler> allocator =+    typename associated_allocator<Handler>::type allocator =       (get_associated_allocator)(handler); -    work_.get_executor().dispatch(-        static_cast<Function&&>(function), allocator);+    work_.get_executor().post(+        ASIO_MOVE_CAST(Function)(function), allocator);   }  private:@@ -232,123 +168,110 @@ class channel_operation::handler_work :   channel_operation::handler_work_base<IoExecutor>,   channel_operation::handler_work_base<-      associated_executor_t<Handler, IoExecutor>, IoExecutor>+      typename associated_executor<Handler, IoExecutor>::type, IoExecutor> { public:   typedef channel_operation::handler_work_base<IoExecutor> base1_type;    typedef channel_operation::handler_work_base<-      associated_executor_t<Handler, IoExecutor>, IoExecutor>+      typename associated_executor<Handler, IoExecutor>::type, IoExecutor>     base2_type; -  handler_work(Handler& handler, const IoExecutor& io_ex) noexcept+  handler_work(Handler& handler, const IoExecutor& io_ex) ASIO_NOEXCEPT     : base1_type(0, io_ex),       base2_type(0, (get_associated_executor)(handler, io_ex))   {   }    template <typename Function>-  void post(Function& function, Handler& handler)-  {-    base2_type::post(base1_type::get_executor(), function, handler);-  }--  template <typename Function>-  void dispatch(Function& function, Handler& handler)+  void complete(Function& function, Handler& handler)   {-    base2_type::dispatch(function, handler);+    base2_type::post(function, handler);   }    template <typename Function>   void immediate(Function& function, Handler& handler, ...)   {-    typedef associated_immediate_executor_t<Handler,-      typename base1_type::executor_type> immediate_ex_type;+    typedef typename associated_immediate_executor<Handler,+      typename base1_type::executor_type>::type immediate_ex_type;      immediate_ex_type immediate_ex = (get_associated_immediate_executor)(         handler, base1_type::get_executor());      (asio::detail::initiate_dispatch_with_executor<immediate_ex_type>(-          immediate_ex))(static_cast<Function&&>(function));+          immediate_ex))(ASIO_MOVE_CAST(Function)(function));   }    template <typename Function>   void immediate(Function& function, Handler&,-      enable_if_t<+      typename enable_if<         is_same<           typename associated_immediate_executor<-            conditional_t<false, Function, Handler>,+            typename conditional<false, Function, Handler>::type,             typename base1_type::executor_type>::               asio_associated_immediate_executor_is_unspecialised,           void         >::value-      >*)+      >::type*)   {     (asio::detail::initiate_post_with_executor<         typename base1_type::executor_type>(           base1_type::get_executor()))(-        static_cast<Function&&>(function));+        ASIO_MOVE_CAST(Function)(function));   } };  template <typename Handler, typename IoExecutor> class channel_operation::handler_work<     Handler, IoExecutor,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_executor<Handler,           IoExecutor>::asio_associated_executor_is_unspecialised,         void       >::value-    >-  > : handler_work_base<IoExecutor>+    >::type> : handler_work_base<IoExecutor> { public:   typedef channel_operation::handler_work_base<IoExecutor> base1_type; -  handler_work(Handler&, const IoExecutor& io_ex) noexcept+  handler_work(Handler&, const IoExecutor& io_ex) ASIO_NOEXCEPT     : base1_type(0, io_ex)   {   }    template <typename Function>-  void post(Function& function, Handler& handler)-  {-    base1_type::post(base1_type::get_executor(), function, handler);-  }--  template <typename Function>-  void dispatch(Function& function, Handler& handler)+  void complete(Function& function, Handler& handler)   {-    base1_type::dispatch(function, handler);+    base1_type::post(function, handler);   }    template <typename Function>   void immediate(Function& function, Handler& handler, ...)   {-    typedef associated_immediate_executor_t<Handler,-      typename base1_type::executor_type> immediate_ex_type;+    typedef typename associated_immediate_executor<Handler,+      typename base1_type::executor_type>::type immediate_ex_type;      immediate_ex_type immediate_ex = (get_associated_immediate_executor)(         handler, base1_type::get_executor());      (asio::detail::initiate_dispatch_with_executor<immediate_ex_type>(-          immediate_ex))(static_cast<Function&&>(function));+          immediate_ex))(ASIO_MOVE_CAST(Function)(function));   }    template <typename Function>   void immediate(Function& function, Handler& handler,-      enable_if_t<+      typename enable_if<         is_same<           typename associated_immediate_executor<-            conditional_t<false, Function, Handler>,+            typename conditional<false, Function, Handler>::type,             typename base1_type::executor_type>::               asio_associated_immediate_executor_is_unspecialised,           void         >::value-      >*)+      >::type*)   {-    base1_type::post(base1_type::get_executor(), function, handler);+    base1_type::post(function, handler);   } }; 
+ link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_payload.hpp view
@@ -0,0 +1,139 @@+//+// experimental/detail/channel_payload.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXPERIMENTAL_DETAIL_CHANNEL_PAYLOAD_HPP+#define ASIO_EXPERIMENTAL_DETAIL_CHANNEL_PAYLOAD_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/error_code.hpp"+#include "asio/experimental/detail/channel_message.hpp"++#if defined(ASIO_HAS_STD_VARIANT)+# include <variant>+#endif // defined(ASIO_HAS_STD_VARIANT)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {+namespace detail {++template <typename... Signatures>+class channel_payload;++template <typename R>+class channel_payload<R()>+{+public:+  explicit channel_payload(channel_message<R()>)+  {+  }++  template <typename Handler>+  void receive(Handler& handler)+  {+    ASIO_MOVE_OR_LVALUE(Handler)(handler)();+  }+};++template <typename Signature>+class channel_payload<Signature>+{+public:+  channel_payload(ASIO_MOVE_ARG(channel_message<Signature>) m)+    : message_(ASIO_MOVE_CAST(channel_message<Signature>)(m))+  {+  }++  template <typename Handler>+  void receive(Handler& handler)+  {+    message_.receive(handler);+  }++private:+  channel_message<Signature> message_;+};++#if defined(ASIO_HAS_STD_VARIANT)++template <typename... Signatures>+class channel_payload+{+public:+  template <typename Signature>+  channel_payload(ASIO_MOVE_ARG(channel_message<Signature>) m)+    : message_(ASIO_MOVE_CAST(channel_message<Signature>)(m))+  {+  }++  template <typename Handler>+  void receive(Handler& handler)+  {+    std::visit(+        [&](auto& message)+        {+          message.receive(handler);+        }, message_);+  }++private:+  std::variant<channel_message<Signatures>...> message_;+};++#else // defined(ASIO_HAS_STD_VARIANT)++template <typename R1, typename R2>+class channel_payload<R1(), R2(asio::error_code)>+{+public:+  typedef channel_message<R1()> void_message_type;+  typedef channel_message<R2(asio::error_code)> error_message_type;++  channel_payload(ASIO_MOVE_ARG(void_message_type))+    : message_(0, asio::error_code()),+      empty_(true)+  {+  }++  channel_payload(ASIO_MOVE_ARG(error_message_type) m)+    : message_(ASIO_MOVE_CAST(error_message_type)(m)),+      empty_(false)+  {+  }++  template <typename Handler>+  void receive(Handler& handler)+  {+    if (empty_)+      channel_message<R1()>(0).receive(handler);+    else+      message_.receive(handler);+  }++private:+  error_message_type message_;+  bool empty_;+};++#endif // defined(ASIO_HAS_STD_VARIANT)++} // namespace detail+} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_DETAIL_CHANNEL_PAYLOAD_HPP
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_receive_op.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_receive_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,10 +17,11 @@  #include "asio/detail/config.hpp" #include "asio/detail/bind_handler.hpp"-#include "asio/detail/completion_handler.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/error.hpp"+#include "asio/experimental/detail/channel_handler.hpp" #include "asio/experimental/detail/channel_operation.hpp"+#include "asio/experimental/detail/channel_payload.hpp"  #include "asio/detail/push_options.hpp" @@ -37,14 +38,9 @@     func_(this, immediate_op, &payload);   } -  void post(Payload payload)-  {-    func_(this, post_op, &payload);-  }--  void dispatch(Payload payload)+  void complete(Payload payload)   {-    func_(this, dispatch_op, &payload);+    func_(this, complete_op, &payload);   }  protected:@@ -63,7 +59,7 @@   template <typename... Args>   channel_receive_op(Handler& handler, const IoExecutor& io_ex)     : channel_receive<Payload>(&channel_receive_op::do_action),-      handler_(static_cast<Handler&&>(handler)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -79,8 +75,8 @@      // Take ownership of the operation's outstanding work.     channel_operation::handler_work<Handler, IoExecutor> w(-        static_cast<channel_operation::handler_work<Handler, IoExecutor>&&>(-          o->work_));+        ASIO_MOVE_CAST2(channel_operation::handler_work<+          Handler, IoExecutor>)(o->work_));      // Make a copy of the handler so that the memory can be deallocated before     // the handler is posted. Even if we're not about to post the handler, a@@ -91,17 +87,15 @@     if (a != channel_operation::destroy_op)     {       Payload* payload = static_cast<Payload*>(v);-      asio::detail::completion_payload_handler<Payload, Handler> handler(-          static_cast<Payload&&>(*payload), o->handler_);+      channel_handler<Payload, Handler> handler(+          ASIO_MOVE_CAST(Payload)(*payload), o->handler_);       p.h = asio::detail::addressof(handler.handler_);       p.reset();       ASIO_HANDLER_INVOCATION_BEGIN(());       if (a == channel_operation::immediate_op)         w.immediate(handler, handler.handler_, 0);-      else if (a == channel_operation::dispatch_op)-        w.dispatch(handler, handler.handler_);       else-        w.post(handler, handler.handler_);+        w.complete(handler, handler.handler_);       ASIO_HANDLER_INVOCATION_END;     }     else
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_send_functions.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_send_functions.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,9 +17,9 @@  #include "asio/detail/config.hpp" #include "asio/async_result.hpp"-#include "asio/detail/completion_message.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error_code.hpp"+#include "asio/experimental/detail/channel_message.hpp"  #include "asio/detail/push_options.hpp" @@ -35,76 +35,48 @@ { public:   template <typename... Args2>-  enable_if_t<-    is_constructible<asio::detail::completion_message<R(Args...)>,-      int, Args2...>::value,-    bool-  > try_send(Args2&&... args)-  {-    typedef asio::detail::completion_message<R(Args...)> message_type;-    Derived* self = static_cast<Derived*>(this);-    return self->service_->template try_send<message_type>(-        self->impl_, false, static_cast<Args2&&>(args)...);-  }--  template <typename... Args2>-  enable_if_t<-    is_constructible<asio::detail::completion_message<R(Args...)>,-      int, Args2...>::value,+  typename enable_if<+    is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value,     bool-  > try_send_via_dispatch(Args2&&... args)+  >::type try_send(ASIO_MOVE_ARG(Args2)... args)   {-    typedef asio::detail::completion_message<R(Args...)> message_type;+    typedef typename detail::channel_message<R(Args...)> message_type;     Derived* self = static_cast<Derived*>(this);     return self->service_->template try_send<message_type>(-        self->impl_, true, static_cast<Args2&&>(args)...);-  }--  template <typename... Args2>-  enable_if_t<-    is_constructible<asio::detail::completion_message<R(Args...)>,-      int, Args2...>::value,-    std::size_t-  > try_send_n(std::size_t count, Args2&&... args)-  {-    typedef asio::detail::completion_message<R(Args...)> message_type;-    Derived* self = static_cast<Derived*>(this);-    return self->service_->template try_send_n<message_type>(-        self->impl_, count, false, static_cast<Args2&&>(args)...);+        self->impl_, ASIO_MOVE_CAST(Args2)(args)...);   }    template <typename... Args2>-  enable_if_t<-    is_constructible<asio::detail::completion_message<R(Args...)>,-      int, Args2...>::value,+  typename enable_if<+    is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value,     std::size_t-  > try_send_n_via_dispatch(std::size_t count, Args2&&... args)+  >::type try_send_n(std::size_t count, ASIO_MOVE_ARG(Args2)... args)   {-    typedef asio::detail::completion_message<R(Args...)> message_type;+    typedef typename detail::channel_message<R(Args...)> message_type;     Derived* self = static_cast<Derived*>(this);     return self->service_->template try_send_n<message_type>(-        self->impl_, count, true, static_cast<Args2&&>(args)...);+        self->impl_, count, ASIO_MOVE_CAST(Args2)(args)...);   }    template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))         CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>   auto async_send(Args... args,-      CompletionToken&& token+      ASIO_MOVE_ARG(CompletionToken) token         ASIO_DEFAULT_COMPLETION_TOKEN(Executor))     -> decltype(         async_initiate<CompletionToken, void (asio::error_code)>(-          declval<typename conditional_t<false, CompletionToken,-            Derived>::initiate_async_send>(), token,-          declval<typename conditional_t<false, CompletionToken,-            Derived>::payload_type>()))+          declval<typename conditional<false, CompletionToken,+            Derived>::type::initiate_async_send>(), token,+          declval<typename conditional<false, CompletionToken,+            Derived>::type::payload_type>()))   {     typedef typename Derived::payload_type payload_type;-    typedef asio::detail::completion_message<R(Args...)> message_type;+    typedef typename detail::channel_message<R(Args...)> message_type;     Derived* self = static_cast<Derived*>(this);     return async_initiate<CompletionToken, void (asio::error_code)>(         typename Derived::initiate_async_send(self), token,-        payload_type(message_type(0, static_cast<Args&&>(args)...)));+        payload_type(message_type(0, ASIO_MOVE_CAST(Args)(args)...)));   } }; @@ -118,76 +90,48 @@   using channel_send_functions<Derived, Executor, Signatures...>::async_send;    template <typename... Args2>-  enable_if_t<-    is_constructible<asio::detail::completion_message<R(Args...)>,-      int, Args2...>::value,-    bool-  > try_send(Args2&&... args)-  {-    typedef asio::detail::completion_message<R(Args...)> message_type;-    Derived* self = static_cast<Derived*>(this);-    return self->service_->template try_send<message_type>(-        self->impl_, false, static_cast<Args2&&>(args)...);-  }--  template <typename... Args2>-  enable_if_t<-    is_constructible<asio::detail::completion_message<R(Args...)>,-      int, Args2...>::value,+  typename enable_if<+    is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value,     bool-  > try_send_via_dispatch(Args2&&... args)+  >::type try_send(ASIO_MOVE_ARG(Args2)... args)   {-    typedef asio::detail::completion_message<R(Args...)> message_type;+    typedef typename detail::channel_message<R(Args...)> message_type;     Derived* self = static_cast<Derived*>(this);     return self->service_->template try_send<message_type>(-        self->impl_, true, static_cast<Args2&&>(args)...);-  }--  template <typename... Args2>-  enable_if_t<-    is_constructible<asio::detail::completion_message<R(Args...)>,-      int, Args2...>::value,-    std::size_t-  > try_send_n(std::size_t count, Args2&&... args)-  {-    typedef asio::detail::completion_message<R(Args...)> message_type;-    Derived* self = static_cast<Derived*>(this);-    return self->service_->template try_send_n<message_type>(-        self->impl_, count, false, static_cast<Args2&&>(args)...);+        self->impl_, ASIO_MOVE_CAST(Args2)(args)...);   }    template <typename... Args2>-  enable_if_t<-    is_constructible<asio::detail::completion_message<R(Args...)>,-      int, Args2...>::value,+  typename enable_if<+    is_constructible<detail::channel_message<R(Args...)>, int, Args2...>::value,     std::size_t-  > try_send_n_via_dispatch(std::size_t count, Args2&&... args)+  >::type try_send_n(std::size_t count, ASIO_MOVE_ARG(Args2)... args)   {-    typedef asio::detail::completion_message<R(Args...)> message_type;+    typedef typename detail::channel_message<R(Args...)> message_type;     Derived* self = static_cast<Derived*>(this);     return self->service_->template try_send_n<message_type>(-        self->impl_, count, true, static_cast<Args2&&>(args)...);+        self->impl_, count, ASIO_MOVE_CAST(Args2)(args)...);   }    template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))         CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>   auto async_send(Args... args,-      CompletionToken&& token+      ASIO_MOVE_ARG(CompletionToken) token         ASIO_DEFAULT_COMPLETION_TOKEN(Executor))     -> decltype(         async_initiate<CompletionToken, void (asio::error_code)>(-          declval<typename conditional_t<false, CompletionToken,-            Derived>::initiate_async_send>(), token,-          declval<typename conditional_t<false, CompletionToken,-            Derived>::payload_type>()))+          declval<typename conditional<false, CompletionToken,+            Derived>::type::initiate_async_send>(), token,+          declval<typename conditional<false, CompletionToken,+            Derived>::type::payload_type>()))   {     typedef typename Derived::payload_type payload_type;-    typedef asio::detail::completion_message<R(Args...)> message_type;+    typedef typename detail::channel_message<R(Args...)> message_type;     Derived* self = static_cast<Derived*>(this);     return async_initiate<CompletionToken, void (asio::error_code)>(         typename Derived::initiate_async_send(self), token,-        payload_type(message_type(0, static_cast<Args&&>(args)...)));+        payload_type(message_type(0, ASIO_MOVE_CAST(Args)(args)...)));   } }; 
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_send_op.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_send_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,6 +21,7 @@ #include "asio/error.hpp" #include "asio/experimental/channel_error.hpp" #include "asio/experimental/detail/channel_operation.hpp"+#include "asio/experimental/detail/channel_payload.hpp"  #include "asio/detail/push_options.hpp" @@ -34,7 +35,7 @@ public:   Payload get_payload()   {-    return static_cast<Payload&&>(payload_);+    return ASIO_MOVE_CAST(Payload)(payload_);   }    void immediate()@@ -42,9 +43,9 @@     func_(this, immediate_op, 0);   } -  void post()+  void complete()   {-    func_(this, post_op, 0);+    func_(this, complete_op, 0);   }    void cancel()@@ -58,9 +59,9 @@   }  protected:-  channel_send(func_type func, Payload&& payload)+  channel_send(func_type func, ASIO_MOVE_ARG(Payload) payload)     : channel_operation(func),-      payload_(static_cast<Payload&&>(payload))+      payload_(ASIO_MOVE_CAST(Payload)(payload))   {   } @@ -74,11 +75,11 @@ public:   ASIO_DEFINE_HANDLER_PTR(channel_send_op); -  channel_send_op(Payload&& payload,+  channel_send_op(ASIO_MOVE_ARG(Payload) payload,       Handler& handler, const IoExecutor& io_ex)     : channel_send<Payload>(&channel_send_op::do_action,-        static_cast<Payload&&>(payload)),-      handler_(static_cast<Handler&&>(handler)),+        ASIO_MOVE_CAST(Payload)(payload)),+      handler_(ASIO_MOVE_CAST(Handler)(handler)),       work_(handler_, io_ex)   {   }@@ -94,8 +95,8 @@      // Take ownership of the operation's outstanding work.     channel_operation::handler_work<Handler, IoExecutor> w(-        static_cast<channel_operation::handler_work<Handler, IoExecutor>&&>(-          o->work_));+        ASIO_MOVE_CAST2(channel_operation::handler_work<+          Handler, IoExecutor>)(o->work_));      asio::error_code ec;     switch (a)@@ -128,7 +129,7 @@       if (a == channel_operation::immediate_op)         w.immediate(handler, handler.handler_, 0);       else-        w.post(handler, handler.handler_);+        w.complete(handler, handler.handler_);       ASIO_HANDLER_INVOCATION_END;     }   }
link/modules/asio-standalone/asio/include/asio/experimental/detail/channel_service.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/channel_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,12 +18,10 @@ #include "asio/detail/config.hpp" #include "asio/associated_cancellation_slot.hpp" #include "asio/cancellation_type.hpp"-#include "asio/detail/completion_message.hpp"-#include "asio/detail/completion_payload.hpp"-#include "asio/detail/completion_payload_handler.hpp" #include "asio/detail/mutex.hpp" #include "asio/detail/op_queue.hpp" #include "asio/execution_context.hpp"+#include "asio/experimental/detail/channel_message.hpp" #include "asio/experimental/detail/channel_receive_op.hpp" #include "asio/experimental/detail/channel_send_op.hpp" #include "asio/experimental/detail/has_signature.hpp"@@ -37,7 +35,7 @@ template <typename Mutex> class channel_service   : public asio::detail::execution_context_service_base<-      channel_service<Mutex>>+      channel_service<Mutex> > { public:   // Possible states for a channel end.@@ -85,7 +83,7 @@   struct implementation_type;    // Constructor.-  channel_service(asio::execution_context& ctx);+  channel_service(execution_context& ctx);    // Destroy all user-defined handler objects owned by the service.   void shutdown();@@ -110,10 +108,10 @@    // Get the capacity of the channel.   std::size_t capacity(-      const base_implementation_type& impl) const noexcept;+      const base_implementation_type& impl) const ASIO_NOEXCEPT;    // Determine whether the channel is open.-  bool is_open(const base_implementation_type& impl) const noexcept;+  bool is_open(const base_implementation_type& impl) const ASIO_NOEXCEPT;    // Reset the channel to its initial state.   template <typename Traits, typename... Signatures>@@ -133,29 +131,29 @@       void* cancellation_key);    // Determine whether a value can be read from the channel without blocking.-  bool ready(const base_implementation_type& impl) const noexcept;+  bool ready(const base_implementation_type& impl) const ASIO_NOEXCEPT;    // Synchronously send a new value into the channel.   template <typename Message, typename Traits,       typename... Signatures, typename... Args>   bool try_send(implementation_type<Traits, Signatures...>& impl,-      bool via_dispatch, Args&&... args);+      ASIO_MOVE_ARG(Args)... args);    // Synchronously send a number of new values into the channel.   template <typename Message, typename Traits,       typename... Signatures, typename... Args>   std::size_t try_send_n(implementation_type<Traits, Signatures...>& impl,-      std::size_t count, bool via_dispatch, Args&&... args);+      std::size_t count, ASIO_MOVE_ARG(Args)... args);    // Asynchronously send a new value into the channel.   template <typename Traits, typename... Signatures,       typename Handler, typename IoExecutor>   void async_send(implementation_type<Traits, Signatures...>& impl,-      typename implementation_type<Traits,-        Signatures...>::payload_type&& payload,+      ASIO_MOVE_ARG2(typename implementation_type<+        Traits, Signatures...>::payload_type) payload,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -164,14 +162,14 @@         Handler, IoExecutor> op;     typename op::ptr p = { asio::detail::addressof(handler),       op::ptr::allocate(handler), 0 };-    p.p = new (p.v) op(static_cast<typename implementation_type<-          Traits, Signatures...>::payload_type&&>(payload), handler, io_ex);+    p.p = new (p.v) op(ASIO_MOVE_CAST2(typename implementation_type<+          Traits, Signatures...>::payload_type)(payload), handler, io_ex);      // Optionally register for per-operation cancellation.     if (slot.is_connected())     {       p.p->cancellation_key_ =-        &slot.template emplace<op_cancellation<Traits, Signatures...>>(+        &slot.template emplace<op_cancellation<Traits, Signatures...> >(             this, &impl);     } @@ -185,7 +183,7 @@   // Synchronously receive a value from the channel.   template <typename Traits, typename... Signatures, typename Handler>   bool try_receive(implementation_type<Traits, Signatures...>& impl,-      Handler&& handler);+      ASIO_MOVE_ARG(Handler) handler);    // Asynchronously receive a value from the channel.   template <typename Traits, typename... Signatures,@@ -193,7 +191,7 @@   void async_receive(implementation_type<Traits, Signatures...>& impl,       Handler& handler, const IoExecutor& io_ex)   {-    associated_cancellation_slot_t<Handler> slot+    typename associated_cancellation_slot<Handler>::type slot       = asio::get_associated_cancellation_slot(handler);      // Allocate and construct an operation to wrap the handler.@@ -208,7 +206,7 @@     if (slot.is_connected())     {       p.p->cancellation_key_ =-        &slot.template emplace<op_cancellation<Traits, Signatures...>>(+        &slot.template emplace<op_cancellation<Traits, Signatures...> >(             this, &impl);     } @@ -222,19 +220,19 @@ private:   // Helper function object to handle a closed notification.   template <typename Payload, typename Signature>-  struct post_receive+  struct complete_receive   {-    explicit post_receive(channel_receive<Payload>* op)+    explicit complete_receive(channel_receive<Payload>* op)       : op_(op)     {     }      template <typename... Args>-    void operator()(Args&&... args)+    void operator()(ASIO_MOVE_ARG(Args)... args)     {-      op_->post(-          asio::detail::completion_message<Signature>(0,-            static_cast<Args&&>(args)...));+      op_->complete(+          channel_message<Signature>(0,+            ASIO_MOVE_CAST(Args)(args)...));     }      channel_receive<Payload>* op_;@@ -299,46 +297,46 @@   typedef typename Traits::template rebind<Signatures...>::other traits_type;    // Type of an element stored in the buffer.-  typedef conditional_t<+  typedef typename conditional<       has_signature<         typename traits_type::receive_cancelled_signature,         Signatures...       >::value,-      conditional_t<+      typename conditional<         has_signature<           typename traits_type::receive_closed_signature,           Signatures...         >::value,-        asio::detail::completion_payload<Signatures...>,-        asio::detail::completion_payload<+        channel_payload<Signatures...>,+        channel_payload<           Signatures...,           typename traits_type::receive_closed_signature         >-      >,-      conditional_t<+      >::type,+      typename conditional<         has_signature<           typename traits_type::receive_closed_signature,           Signatures...,           typename traits_type::receive_cancelled_signature         >::value,-        asio::detail::completion_payload<+        channel_payload<           Signatures...,           typename traits_type::receive_cancelled_signature         >,-        asio::detail::completion_payload<+        channel_payload<           Signatures...,           typename traits_type::receive_cancelled_signature,           typename traits_type::receive_closed_signature         >-      >-    > payload_type;+      >::type+    >::type payload_type;    // Move from another buffer.   void buffer_move_from(implementation_type& other)   {-    buffer_ = static_cast<-        typename traits_type::template container<payload_type>::type&&>(-          other.buffer_);+    buffer_ = ASIO_MOVE_CAST(+        typename traits_type::template container<+          payload_type>::type)(other.buffer_);     other.buffer_clear();   } @@ -351,7 +349,7 @@   // Push a new value to the back of the buffer.   void buffer_push(payload_type payload)   {-    buffer_.push_back(static_cast<payload_type&&>(payload));+    buffer_.push_back(ASIO_MOVE_CAST(payload_type)(payload));   }    // Push new values to the back of the buffer.@@ -366,7 +364,7 @@   // Get the element at the front of the buffer.   payload_type buffer_front()   {-    return static_cast<payload_type&&>(buffer_.front());+    return ASIO_MOVE_CAST(payload_type)(buffer_.front());   }    // Pop a value from the front of the buffer.@@ -396,39 +394,39 @@   typedef typename Traits::template rebind<R()>::other traits_type;    // Type of an element stored in the buffer.-  typedef conditional_t<+  typedef typename conditional<       has_signature<         typename traits_type::receive_cancelled_signature,         R()       >::value,-      conditional_t<+      typename conditional<         has_signature<           typename traits_type::receive_closed_signature,           R()         >::value,-        asio::detail::completion_payload<R()>,-        asio::detail::completion_payload<+        channel_payload<R()>,+        channel_payload<           R(),           typename traits_type::receive_closed_signature         >-      >,-      conditional_t<+      >::type,+      typename conditional<         has_signature<           typename traits_type::receive_closed_signature,           R(),           typename traits_type::receive_cancelled_signature         >::value,-        asio::detail::completion_payload<+        channel_payload<           R(),           typename traits_type::receive_cancelled_signature         >,-        asio::detail::completion_payload<+        channel_payload<           R(),           typename traits_type::receive_cancelled_signature,           typename traits_type::receive_closed_signature         >-      >-    > payload_type;+      >::type+    >::type payload_type;    // Construct with empty buffer.   implementation_type()@@ -467,7 +465,7 @@   // Get the element at the front of the buffer.   payload_type buffer_front()   {-    return payload_type(asio::detail::completion_message<R()>(0));+    return payload_type(channel_message<R()>(0));   }    // Pop a value from the front of the buffer.@@ -499,39 +497,39 @@     traits_type;    // Type of an element stored in the buffer.-  typedef conditional_t<+  typedef typename conditional<       has_signature<         typename traits_type::receive_cancelled_signature,         R(asio::error_code)       >::value,-      conditional_t<+      typename conditional<         has_signature<           typename traits_type::receive_closed_signature,           R(asio::error_code)         >::value,-        asio::detail::completion_payload<R(asio::error_code)>,-        asio::detail::completion_payload<+        channel_payload<R(asio::error_code)>,+        channel_payload<           R(asio::error_code),           typename traits_type::receive_closed_signature         >-      >,-      conditional_t<+      >::type,+      typename conditional<         has_signature<           typename traits_type::receive_closed_signature,           R(asio::error_code),           typename traits_type::receive_cancelled_signature         >::value,-        asio::detail::completion_payload<+        channel_payload<           R(asio::error_code),           typename traits_type::receive_cancelled_signature         >,-        asio::detail::completion_payload<+        channel_payload<           R(asio::error_code),           typename traits_type::receive_cancelled_signature,           typename traits_type::receive_closed_signature         >-      >-    > payload_type;+      >::type+    >::type payload_type;    // Construct with empty buffer.   implementation_type()@@ -543,13 +541,13 @@   // Move from another buffer.   void buffer_move_from(implementation_type& other)   {-    size_ = other.size_;+    size_ = other.buffer_;     other.size_ = 0;     first_ = other.first_;-    other.first_.count_ = 0;-    rest_ = static_cast<-        typename traits_type::template container<buffered_value>::type&&>(-          other.rest_);+    other.first.count_ = 0;+    rest_ = ASIO_MOVE_CAST(+        typename traits_type::template container<+          buffered_value>::type)(other.rest_);     other.buffer_clear();   } @@ -630,7 +628,7 @@   void buffer_clear()   {     size_ = 0;-    first_.count_ = 0;+    first_.count_ == 0;     rest_.clear();   } 
link/modules/asio-standalone/asio/include/asio/experimental/detail/coro_promise_allocator.hpp view
@@ -13,7 +13,6 @@ #define ASIO_EXPERIMENTAL_DETAIL_CORO_PROMISE_ALLOCATOR_HPP  #include "asio/detail/config.hpp"-#include <limits> #include "asio/experimental/coro_traits.hpp"  namespace asio {@@ -65,6 +64,7 @@   return std::numeric_limits<std::size_t>::max(); } + template <typename T, typename First, typename... Args> constexpr std::size_t variadic_first(std::size_t pos = 0u) {@@ -94,14 +94,14 @@   allocator_type get_allocator() const {return alloc_;}    template <typename... Args>-  void* operator new(std::size_t size, Args & ... args)+  void* operator new(const std::size_t size, Args & ... args)   {     return allocate_coroutine(size,         get_variadic<variadic_first<std::allocator_arg_t,           std::decay_t<Args>...>() + 1u>(args...));   } -  void operator delete(void* raw, std::size_t size)+  void operator delete(void* raw, const std::size_t size)   {     deallocate_coroutine<allocator_type>(raw, size);   }
link/modules/asio-standalone/asio/include/asio/experimental/detail/has_signature.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/has_signature.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/experimental/detail/impl/channel_service.hpp view
@@ -2,7 +2,7 @@ // experimental/detail/impl/channel_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,8 +22,7 @@ namespace detail {  template <typename Mutex>-inline channel_service<Mutex>::channel_service(-    asio::execution_context& ctx)+inline channel_service<Mutex>::channel_service(execution_context& ctx)   : asio::detail::execution_context_service_base<channel_service>(ctx),     mutex_(),     impl_list_(0)@@ -156,7 +155,7 @@ template <typename Mutex> inline std::size_t channel_service<Mutex>::capacity(     const channel_service<Mutex>::base_implementation_type& impl)-  const noexcept+  const ASIO_NOEXCEPT {   typename Mutex::scoped_lock lock(impl.mutex_); @@ -166,7 +165,7 @@ template <typename Mutex> inline bool channel_service<Mutex>::is_open(     const channel_service<Mutex>::base_implementation_type& impl)-  const noexcept+  const ASIO_NOEXCEPT {   typename Mutex::scoped_lock lock(impl.mutex_); @@ -205,7 +204,7 @@     {       impl.waiters_.pop();       traits_type::invoke_receive_closed(-          post_receive<payload_type,+          complete_receive<payload_type,             typename traits_type::receive_closed_signature>(               static_cast<channel_receive<payload_type>*>(op)));     }@@ -239,7 +238,7 @@     {       impl.waiters_.pop();       traits_type::invoke_receive_cancelled(-          post_receive<payload_type,+          complete_receive<payload_type,             typename traits_type::receive_cancelled_signature>(               static_cast<channel_receive<payload_type>*>(op)));     }@@ -278,7 +277,7 @@       {         impl.waiters_.pop();         traits_type::invoke_receive_cancelled(-            post_receive<payload_type,+            complete_receive<payload_type,               typename traits_type::receive_cancelled_signature>(                 static_cast<channel_receive<payload_type>*>(op)));       }@@ -303,7 +302,7 @@ template <typename Mutex> inline bool channel_service<Mutex>::ready(     const channel_service<Mutex>::base_implementation_type& impl)-  const noexcept+  const ASIO_NOEXCEPT {   typename Mutex::scoped_lock lock(impl.mutex_); @@ -315,7 +314,7 @@     typename... Signatures, typename... Args> bool channel_service<Mutex>::try_send(     channel_service<Mutex>::implementation_type<Traits, Signatures...>& impl,-    bool via_dispatch, Args&&... args)+    ASIO_MOVE_ARG(Args)... args) {   typedef typename implementation_type<Traits,       Signatures...>::payload_type payload_type;@@ -330,7 +329,7 @@     }   case buffer:     {-      impl.buffer_push(Message(0, static_cast<Args&&>(args)...));+      impl.buffer_push(Message(0, ASIO_MOVE_CAST(Args)(args)...));       impl.receive_state_ = buffer;       if (impl.buffer_size() == impl.max_buffer_size_)         impl.send_state_ = block;@@ -338,17 +337,13 @@     }   case waiter:     {-      payload_type payload(Message(0, static_cast<Args&&>(args)...));+      payload_type payload(Message(0, ASIO_MOVE_CAST(Args)(args)...));       channel_receive<payload_type>* receive_op =         static_cast<channel_receive<payload_type>*>(impl.waiters_.front());       impl.waiters_.pop();+      receive_op->complete(ASIO_MOVE_CAST(payload_type)(payload));       if (impl.waiters_.empty())         impl.send_state_ = impl.max_buffer_size_ ? buffer : block;-      lock.unlock();-      if (via_dispatch)-        receive_op->dispatch(static_cast<payload_type&&>(payload));-      else-        receive_op->post(static_cast<payload_type&&>(payload));       return true;     }   case closed:@@ -364,7 +359,7 @@     typename... Signatures, typename... Args> std::size_t channel_service<Mutex>::try_send_n(     channel_service<Mutex>::implementation_type<Traits, Signatures...>& impl,-		std::size_t count, bool via_dispatch, Args&&... args)+		std::size_t count, ASIO_MOVE_ARG(Args)... args) {   typedef typename implementation_type<Traits,       Signatures...>::payload_type payload_type;@@ -386,7 +381,7 @@     return 0;   } -  payload_type payload(Message(0, static_cast<Args&&>(args)...));+  payload_type payload(Message(0, ASIO_MOVE_CAST(Args)(args)...));    for (std::size_t i = 0; i < count; ++i)   {@@ -399,7 +394,7 @@     case buffer:       {         i += impl.buffer_push_n(count - i,-            static_cast<payload_type&&>(payload));+            ASIO_MOVE_CAST(payload_type)(payload));         impl.receive_state_ = buffer;         if (impl.buffer_size() == impl.max_buffer_size_)           impl.send_state_ = block;@@ -410,13 +405,9 @@         channel_receive<payload_type>* receive_op =           static_cast<channel_receive<payload_type>*>(impl.waiters_.front());         impl.waiters_.pop();+        receive_op->complete(payload);         if (impl.waiters_.empty())           impl.send_state_ = impl.max_buffer_size_ ? buffer : block;-        lock.unlock();-        if (via_dispatch)-          receive_op->dispatch(payload);-        else-          receive_op->post(payload);         break;       }     case closed:@@ -465,9 +456,9 @@       channel_receive<payload_type>* receive_op =         static_cast<channel_receive<payload_type>*>(impl.waiters_.front());       impl.waiters_.pop();+      receive_op->complete(send_op->get_payload());       if (impl.waiters_.empty())         impl.send_state_ = impl.max_buffer_size_ ? buffer : block;-      receive_op->post(send_op->get_payload());       send_op->immediate();       break;     }@@ -484,7 +475,7 @@ template <typename Traits, typename... Signatures, typename Handler> bool channel_service<Mutex>::try_receive(     channel_service<Mutex>::implementation_type<Traits, Signatures...>& impl,-		Handler&& handler)+		ASIO_MOVE_ARG(Handler) handler) {   typedef typename implementation_type<Traits,       Signatures...>::payload_type payload_type;@@ -506,7 +497,7 @@         impl.buffer_pop();         impl.buffer_push(send_op->get_payload());         impl.waiters_.pop();-        send_op->post();+        send_op->complete();       }       else       {@@ -517,9 +508,8 @@       }       lock.unlock();       asio::detail::non_const_lvalue<Handler> handler2(handler);-      asio::detail::completion_payload_handler<-        payload_type, decay_t<Handler>>(-          static_cast<payload_type&&>(payload), handler2.value)();+      channel_handler<payload_type, typename decay<Handler>::type>(+          ASIO_MOVE_CAST(payload_type)(payload), handler2.value)();       return true;     }   case waiter:@@ -528,14 +518,13 @@         static_cast<channel_send<payload_type>*>(impl.waiters_.front());       payload_type payload = send_op->get_payload();       impl.waiters_.pop();+      send_op->complete();       if (impl.waiters_.front() == 0)         impl.receive_state_ = (impl.send_state_ == closed) ? closed : block;-      send_op->post();       lock.unlock();       asio::detail::non_const_lvalue<Handler> handler2(handler);-      asio::detail::completion_payload_handler<-        payload_type, decay_t<Handler>>(-          static_cast<payload_type&&>(payload), handler2.value)();+      channel_handler<payload_type, typename decay<Handler>::type>(+          ASIO_MOVE_CAST(payload_type)(payload), handler2.value)();       return true;     }   case closed:@@ -572,14 +561,14 @@   case buffer:     {       payload_type payload(-          static_cast<payload_type&&>(impl.buffer_front()));+          ASIO_MOVE_CAST(payload_type)(impl.buffer_front()));       if (channel_send<payload_type>* send_op =           static_cast<channel_send<payload_type>*>(impl.waiters_.front()))       {         impl.buffer_pop();         impl.buffer_push(send_op->get_payload());         impl.waiters_.pop();-        send_op->post();+        send_op->complete();       }       else       {@@ -588,7 +577,7 @@           impl.receive_state_ = (impl.send_state_ == closed) ? closed : block;         impl.send_state_ = (impl.send_state_ == closed) ? closed : buffer;       }-      receive_op->immediate(static_cast<payload_type&&>(payload));+      receive_op->immediate(ASIO_MOVE_CAST(payload_type)(payload));       break;     }   case waiter:@@ -597,17 +586,17 @@         static_cast<channel_send<payload_type>*>(impl.waiters_.front());       payload_type payload = send_op->get_payload();       impl.waiters_.pop();+      send_op->complete();       if (impl.waiters_.front() == 0)         impl.receive_state_ = (impl.send_state_ == closed) ? closed : block;-      send_op->post();-      receive_op->immediate(static_cast<payload_type&&>(payload));+      receive_op->immediate(ASIO_MOVE_CAST(payload_type)(payload));       break;     }   case closed:   default:     {       traits_type::invoke_receive_closed(-          post_receive<payload_type,+          complete_receive<payload_type,             typename traits_type::receive_closed_signature>(receive_op));       break;     }
link/modules/asio-standalone/asio/include/asio/experimental/detail/partial_promise.hpp view
@@ -54,12 +54,12 @@ struct partial_promise_base {   template <typename Executor, typename Token, typename... Args>-  void* operator new(std::size_t size, Executor&, Token& tk, Args&...)+  void* operator new(const std::size_t size, Executor&, Token& tk, Args&...)   {     return allocate_coroutine<Allocator>(size, get_associated_allocator(tk));   } -  void operator delete(void* raw, std::size_t size)+  void operator delete(void* raw, const std::size_t size)   {     deallocate_coroutine<Allocator>(raw, size);   }@@ -110,7 +110,9 @@   } }; -} // namespace detail+++}; // namespace detail } // namespace experimental } // namespace asio 
link/modules/asio-standalone/asio/include/asio/experimental/impl/as_single.hpp view
@@ -2,7 +2,7 @@ // experimental/impl/as_single.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,12 +16,16 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+ #include <tuple>+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp" @@ -38,32 +42,33 @@    template <typename CompletionToken>   as_single_handler(as_single_t<CompletionToken> e)-    : handler_(static_cast<CompletionToken&&>(e.token_))+    : handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_))   {   }    template <typename RedirectedHandler>-  as_single_handler(RedirectedHandler&& h)-    : handler_(static_cast<RedirectedHandler&&>(h))+  as_single_handler(ASIO_MOVE_ARG(RedirectedHandler) h)+    : handler_(ASIO_MOVE_CAST(RedirectedHandler)(h))   {   }    void operator()()   {-    static_cast<Handler&&>(handler_)();+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)();   }    template <typename Arg>-  void operator()(Arg&& arg)+  void operator()(ASIO_MOVE_ARG(Arg) arg)   {-    static_cast<Handler&&>(handler_)(static_cast<Arg&&>(arg));+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        ASIO_MOVE_CAST(Arg)(arg));   }    template <typename... Args>-  void operator()(Args&&... args)+  void operator()(ASIO_MOVE_ARG(Args)... args)   {-    static_cast<Handler&&>(handler_)(-        std::make_tuple(static_cast<Args&&>(args)...));+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        std::make_tuple(ASIO_MOVE_CAST(Args)(args)...));   }  //private:@@ -71,6 +76,32 @@ };  template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    as_single_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    as_single_handler<Handler>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation(     as_single_handler<Handler>* this_handler) {@@ -78,6 +109,30 @@         this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    as_single_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    as_single_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature> struct as_single_signature {@@ -99,7 +154,7 @@ template <typename R, typename... Args> struct as_single_signature<R(Args...)> {-  typedef R type(std::tuple<decay_t<Args>...>);+  typedef R type(std::tuple<typename decay<Args>::type...>); };  } // namespace detail@@ -110,45 +165,44 @@ template <typename CompletionToken, typename Signature> struct async_result<experimental::as_single_t<CompletionToken>, Signature> {+  typedef typename async_result<CompletionToken,+    typename experimental::detail::as_single_signature<Signature>::type>+      ::return_type return_type;+   template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;--    template <typename Handler, typename... Args>-    void operator()(Handler&& handler, Args&&... args) &&+    init_wrapper(Initiation init)+      : initiation_(ASIO_MOVE_CAST(Initiation)(init))     {-      static_cast<Initiation&&>(*this)(-          experimental::detail::as_single_handler<decay_t<Handler>>(-            static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<const Initiation&>(*this)(-          experimental::detail::as_single_handler<decay_t<Handler>>(-            static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          experimental::detail::as_single_handler<+            typename decay<Handler>::type>(+              ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }++    Initiation initiation_;   };    template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<CompletionToken,-        typename experimental::detail::as_single_signature<Signature>::type>(-          init_wrapper<decay_t<Initiation>>(-            static_cast<Initiation&&>(initiation)),-          token.token_, static_cast<Args&&>(args)...))+  static return_type initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)   {     return async_initiate<CompletionToken,       typename experimental::detail::as_single_signature<Signature>::type>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.token_, static_cast<Args&&>(args)...);+        init_wrapper<typename decay<Initiation>::type>(+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.token_, ASIO_MOVE_CAST(Args)(args)...);   } }; @@ -158,15 +212,19 @@     experimental::detail::as_single_handler<Handler>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const experimental::detail::as_single_handler<Handler>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const experimental::detail::as_single_handler<Handler>& h)+    ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const experimental::detail::as_single_handler<Handler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const experimental::detail::as_single_handler<Handler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }
link/modules/asio-standalone/asio/include/asio/experimental/impl/channel_error.ipp view
@@ -2,7 +2,7 @@ // experimental/impl/channel_error.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -28,7 +28,7 @@ class channel_category : public asio::error_category { public:-  const char* name() const noexcept+  const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT   {     return "asio.channel";   }
+ link/modules/asio-standalone/asio/include/asio/experimental/impl/co_composed.hpp view
@@ -0,0 +1,1175 @@+//+// experimental/impl/co_composed.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_IMPL_EXPERIMENTAL_CO_COMPOSED_HPP+#define ASIO_IMPL_EXPERIMENTAL_CO_COMPOSED_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <new>+#include <tuple>+#include <variant>+#include "asio/associated_cancellation_slot.hpp"+#include "asio/associator.hpp"+#include "asio/async_result.hpp"+#include "asio/cancellation_state.hpp"+#include "asio/detail/composed_work.hpp"+#include "asio/detail/recycling_allocator.hpp"+#include "asio/detail/throw_error.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/error.hpp"++#if defined(ASIO_HAS_STD_COROUTINE)+# include <coroutine>+#else // defined(ASIO_HAS_STD_COROUTINE)+# include <experimental/coroutine>+#endif // defined(ASIO_HAS_STD_COROUTINE)++#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+#  include "asio/detail/source_location.hpp"+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {+namespace detail {++#if defined(ASIO_HAS_STD_COROUTINE)+using std::coroutine_handle;+using std::suspend_always;+using std::suspend_never;+#else // defined(ASIO_HAS_STD_COROUTINE)+using std::experimental::coroutine_handle;+using std::experimental::suspend_always;+using std::experimental::suspend_never;+#endif // defined(ASIO_HAS_STD_COROUTINE)++using asio::detail::composed_io_executors;+using asio::detail::composed_work;+using asio::detail::composed_work_guard;+using asio::detail::get_composed_io_executor;+using asio::detail::make_composed_io_executors;+using asio::detail::recycling_allocator;+using asio::detail::throw_error;++template <typename Executors, typename Handler, typename Return>+class co_composed_state;++template <typename Executors, typename Handler, typename Return>+class co_composed_handler_base;++template <typename Executors, typename Handler, typename Return>+class co_composed_promise;++template <completion_signature... Signatures>+class co_composed_returns+{+};++struct co_composed_on_suspend+{+  void (*fn_)(void*) = nullptr;+  void* arg_ = nullptr;+};++template <typename... T>+struct co_composed_completion : std::tuple<T&&...>+{+  template <typename... U>+  co_composed_completion(U&&... u) noexcept+    : std::tuple<T&&...>(std::forward<U>(u)...)+  {+  }+};++template <typename Executors, typename Handler,+    typename Return, typename Signature>+class co_composed_state_return_overload;++template <typename Executors, typename Handler,+    typename Return, typename R, typename... Args>+class co_composed_state_return_overload<+    Executors, Handler, Return, R(Args...)>+{+public:+  using derived_type = co_composed_state<Executors, Handler, Return>;+  using promise_type = co_composed_promise<Executors, Handler, Return>;+  using return_type = std::tuple<Args...>;++  void on_cancellation_complete_with(Args... args)+  {+    derived_type& state = *static_cast<derived_type*>(this);+    state.return_value_ = std::make_tuple(std::move(args)...);+    state.cancellation_on_suspend_fn(+        [](void* p)+        {+          auto& promise = *static_cast<promise_type*>(p);++          co_composed_handler_base<Executors, Handler,+            Return> composed_handler(promise);++          Handler handler(std::move(promise.state().handler_));+          return_type result(+              std::move(std::get<return_type>(promise.state().return_value_)));++          co_composed_handler_base<Executors, Handler,+            Return>(std::move(composed_handler));++          std::apply(std::move(handler), std::move(result));+        });+  }+};++template <typename Executors, typename Handler, typename Return>+class co_composed_state_return;++template <typename Executors, typename Handler, typename... Signatures>+class co_composed_state_return<+    Executors, Handler, co_composed_returns<Signatures...>>+  : public co_composed_state_return_overload<Executors,+      Handler, co_composed_returns<Signatures...>, Signatures>...+{+public:+  using co_composed_state_return_overload<Executors,+    Handler, co_composed_returns<Signatures...>,+      Signatures>::on_cancellation_complete_with...;++private:+  template <typename, typename, typename, typename>+    friend class co_composed_promise_return_overload;+  template <typename, typename, typename, typename>+    friend class co_composed_state_return_overload;++  std::variant<std::monostate,+    typename co_composed_state_return_overload<+      Executors, Handler, co_composed_returns<Signatures...>,+        Signatures>::return_type...> return_value_;+};++template <typename Executors, typename Handler,+    typename Return, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend_impl;++template <typename Executors, typename Handler, typename Return>+struct co_composed_state_default_cancellation_on_suspend_impl<+    Executors, Handler, Return>+{+  static constexpr void (*fn())(void*)+  {+    return nullptr;+  }+};++template <typename Executors, typename Handler, typename Return,+    typename R, typename... Args, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend_impl<+    Executors, Handler, Return, R(Args...), Signatures...>+{+  static constexpr void (*fn())(void*)+  {+    return co_composed_state_default_cancellation_on_suspend_impl<+      Executors, Handler, Return, Signatures...>::fn();+  }+};++template <typename Executors, typename Handler, typename Return,+    typename R, typename... Args, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend_impl<Executors,+    Handler, Return, R(asio::error_code, Args...), Signatures...>+{+  using promise_type = co_composed_promise<Executors, Handler, Return>;+  using return_type = std::tuple<asio::error_code, Args...>;++  static constexpr void (*fn())(void*)+  {+    if constexpr ((is_constructible<Args>::value && ...))+    {+      return [](void* p)+      {+        auto& promise = *static_cast<promise_type*>(p);++        co_composed_handler_base<Executors, Handler,+          Return> composed_handler(promise);++        Handler handler(std::move(promise.state().handler_));++        co_composed_handler_base<Executors, Handler,+          Return>(std::move(composed_handler));++        std::move(handler)(+            asio::error_code(asio::error::operation_aborted),+            Args{}...);+      };+    }+    else+    {+      return co_composed_state_default_cancellation_on_suspend_impl<+        Executors, Handler, Return, Signatures...>::fn();+    }+  }+};++template <typename Executors, typename Handler, typename Return,+    typename R, typename... Args, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend_impl<Executors,+    Handler, Return, R(std::exception_ptr, Args...), Signatures...>+{+  using promise_type = co_composed_promise<Executors, Handler, Return>;+  using return_type = std::tuple<std::exception_ptr, Args...>;++  static constexpr void (*fn())(void*)+  {+    if constexpr ((is_constructible<Args>::value && ...))+    {+      return [](void* p)+      {+        auto& promise = *static_cast<promise_type*>(p);++        co_composed_handler_base<Executors, Handler,+          Return> composed_handler(promise);++        Handler handler(std::move(promise.state().handler_));++        co_composed_handler_base<Executors, Handler,+          Return>(std::move(composed_handler));++        std::move(handler)(+            std::make_exception_ptr(+              asio::system_error(+                asio::error::operation_aborted, "co_await")),+            Args{}...);+      };+    }+    else+    {+      return co_composed_state_default_cancellation_on_suspend_impl<+        Executors, Handler, Return, Signatures...>::fn();+    }+  }+};++template <typename Executors, typename Handler, typename Return>+struct co_composed_state_default_cancellation_on_suspend;++template <typename Executors, typename Handler, typename... Signatures>+struct co_composed_state_default_cancellation_on_suspend<+    Executors, Handler, co_composed_returns<Signatures...>>+  : co_composed_state_default_cancellation_on_suspend_impl<Executors,+      Handler, co_composed_returns<Signatures...>, Signatures...>+{+};++template <typename Executors, typename Handler, typename Return>+class co_composed_state_cancellation+{+public:+  using cancellation_slot_type = cancellation_slot;++  cancellation_slot_type get_cancellation_slot() const noexcept+  {+    return cancellation_state_.slot();+  }++  cancellation_state get_cancellation_state() const noexcept+  {+    return cancellation_state_;+  }++  void reset_cancellation_state()+  {+    cancellation_state_ = cancellation_state(+        (get_associated_cancellation_slot)(+          static_cast<co_composed_state<Executors, Handler, Return>*>(+            this)->handler()));+  }++  template <typename Filter>+  void reset_cancellation_state(Filter filter)+  {+    cancellation_state_ = cancellation_state(+        (get_associated_cancellation_slot)(+          static_cast<co_composed_state<Executors, Handler, Return>*>(+            this)->handler()), filter, filter);+  }++  template <typename InFilter, typename OutFilter>+  void reset_cancellation_state(InFilter&& in_filter, OutFilter&& out_filter)+  {+    cancellation_state_ = cancellation_state(+        (get_associated_cancellation_slot)(+          static_cast<co_composed_state<Executors, Handler, Return>*>(+            this)->handler()),+        std::forward<InFilter>(in_filter),+        std::forward<OutFilter>(out_filter));+  }++  cancellation_type_t cancelled() const noexcept+  {+    return cancellation_state_.cancelled();+  }++  void clear_cancellation_slot() noexcept+  {+    cancellation_state_.slot().clear();+  }++  [[nodiscard]] bool throw_if_cancelled() const noexcept+  {+    return throw_if_cancelled_;+  }++  void throw_if_cancelled(bool b) noexcept+  {+    throw_if_cancelled_ = b;+  }++  [[nodiscard]] bool complete_if_cancelled() const noexcept+  {+    return complete_if_cancelled_;+  }++  void complete_if_cancelled(bool b) noexcept+  {+    complete_if_cancelled_ = b;+  }++private:+  template <typename, typename, typename>+    friend class co_composed_promise;+  template <typename, typename, typename, typename>+    friend class co_composed_state_return_overload;++  void cancellation_on_suspend_fn(void (*fn)(void*))+  {+    cancellation_on_suspend_fn_ = fn;+  }++  void check_for_cancellation_on_transform()+  {+    if (throw_if_cancelled_ && !!cancelled())+      throw_error(asio::error::operation_aborted, "co_await");+  }++  bool check_for_cancellation_on_suspend(+      co_composed_promise<Executors, Handler, Return>& promise) noexcept+  {+    if (complete_if_cancelled_ && !!cancelled() && cancellation_on_suspend_fn_)+    {+      promise.state().work_.reset();+      promise.state().on_suspend_->fn_ = cancellation_on_suspend_fn_;+      promise.state().on_suspend_->arg_ = &promise;+      return false;+    }+    return true;+  }++  cancellation_state cancellation_state_;+  void (*cancellation_on_suspend_fn_)(void*) =+    co_composed_state_default_cancellation_on_suspend<+      Executors, Handler, Return>::fn();+  bool throw_if_cancelled_ = false;+  bool complete_if_cancelled_ = true;+};++template <typename Executors, typename Handler, typename Return>+  requires is_same<+    typename associated_cancellation_slot<+      Handler, cancellation_slot+    >::asio_associated_cancellation_slot_is_unspecialised,+    void>::value+class co_composed_state_cancellation<Executors, Handler, Return>+{+public:+  void reset_cancellation_state()+  {+  }++  template <typename Filter>+  void reset_cancellation_state(Filter)+  {+  }++  template <typename InFilter, typename OutFilter>+  void reset_cancellation_state(InFilter&&, OutFilter&&)+  {+  }++  cancellation_type_t cancelled() const noexcept+  {+    return cancellation_type::none;+  }++  void clear_cancellation_slot() noexcept+  {+  }++  [[nodiscard]] bool throw_if_cancelled() const noexcept+  {+    return false;+  }++  void throw_if_cancelled(bool) noexcept+  {+  }++  [[nodiscard]] bool complete_if_cancelled() const noexcept+  {+    return false;+  }++  void complete_if_cancelled(bool) noexcept+  {+  }++private:+  template <typename, typename, typename>+    friend class co_composed_promise;+  template <typename, typename, typename, typename>+    friend class co_composed_state_return_overload;++  void cancellation_on_suspend_fn(void (*)(void*))+  {+  }++  void check_for_cancellation_on_transform() noexcept+  {+  }++  bool check_for_cancellation_on_suspend(+      co_composed_promise<Executors, Handler, Return>&) noexcept+  {+    return true;+  }+};++template <typename Executors, typename Handler, typename Return>+class co_composed_state+  : public co_composed_state_return<Executors, Handler, Return>,+    public co_composed_state_cancellation<Executors, Handler, Return>+{+public:+  using io_executor_type = typename composed_work_guard<+    typename composed_work<Executors>::head_type>::executor_type;++  template <typename H>+  co_composed_state(composed_io_executors<Executors>&& executors,+      H&& h, co_composed_on_suspend& on_suspend)+    : work_(std::move(executors)),+      handler_(std::forward<H>(h)),+      on_suspend_(&on_suspend)+  {+    this->reset_cancellation_state(enable_terminal_cancellation());+  }++  io_executor_type get_io_executor() const noexcept+  {+    return work_.head_.get_executor();+  }++  template <typename... Args>+  [[nodiscard]] co_composed_completion<Args...> complete(Args&&... args)+    requires requires { declval<Handler>()(std::forward<Args>(args)...); }+  {+    return co_composed_completion<Args...>(std::forward<Args>(args)...);+  }++  const Handler& handler() const noexcept+  {+    return handler_;+  }++private:+  template <typename, typename, typename>+    friend class co_composed_handler_base;+  template <typename, typename, typename>+    friend class co_composed_promise;+  template <typename, typename, typename, typename>+    friend class co_composed_promise_return_overload;+  template <typename, typename, typename>+    friend class co_composed_state_cancellation;+  template <typename, typename, typename, typename>+    friend class co_composed_state_return_overload;+  template <typename, typename, typename, typename...>+    friend struct co_composed_state_default_cancellation_on_suspend_impl;++  composed_work<Executors> work_;+  Handler handler_;+  co_composed_on_suspend* on_suspend_;+};++template <typename Executors, typename Handler, typename Return>+class co_composed_handler_cancellation+{+public:+  using cancellation_slot_type = cancellation_slot;++  cancellation_slot_type get_cancellation_slot() const noexcept+  {+    return static_cast<+      const co_composed_handler_base<Executors, Handler, Return>*>(+        this)->promise().state().get_cancellation_slot();+  }+};++template <typename Executors, typename Handler, typename Return>+  requires is_same<+    typename associated_cancellation_slot<+      Handler, cancellation_slot+    >::asio_associated_cancellation_slot_is_unspecialised,+    void>::value+class co_composed_handler_cancellation<Executors, Handler, Return>+{+};++template <typename Executors, typename Handler, typename Return>+class co_composed_handler_base :+  public co_composed_handler_cancellation<Executors, Handler, Return>+{+public:+  co_composed_handler_base(+      co_composed_promise<Executors, Handler, Return>& p) noexcept+    : p_(&p)+  {+  }++  co_composed_handler_base(co_composed_handler_base&& other) noexcept+    : p_(std::exchange(other.p_, nullptr))+  {+  }++  ~co_composed_handler_base()+  {+    if (p_) [[unlikely]]+      p_->destroy();+  }++  co_composed_promise<Executors, Handler, Return>& promise() const noexcept+  {+    return *p_;+  }++protected:+  void resume(void* result)+  {+    co_composed_on_suspend on_suspend{};+    std::exchange(p_, nullptr)->resume(p_, result, on_suspend);+    if (on_suspend.fn_)+      on_suspend.fn_(on_suspend.arg_);+  }++private:+  co_composed_promise<Executors, Handler, Return>* p_;+};++template <typename Executors, typename Handler,+    typename Return, typename Signature>+class co_composed_handler;++template <typename Executors, typename Handler,+    typename Return, typename R, typename... Args>+class co_composed_handler<Executors, Handler, Return, R(Args...)>+  : public co_composed_handler_base<Executors, Handler, Return>+{+public:+  using co_composed_handler_base<Executors,+    Handler, Return>::co_composed_handler_base;++  using result_type = std::tuple<typename decay<Args>::type...>;++  template <typename... T>+  void operator()(T&&... args)+  {+    result_type result(std::forward<T>(args)...);+    this->resume(&result);+  }++  static auto on_resume(void* result)+  {+    auto& args = *static_cast<result_type*>(result);+    if constexpr (sizeof...(Args) == 0)+      return;+    else if constexpr (sizeof...(Args) == 1)+      return std::move(std::get<0>(args));+    else+      return std::move(args);+  }+};++template <typename Executors, typename Handler,+    typename Return, typename R, typename... Args>+class co_composed_handler<Executors, Handler,+    Return, R(asio::error_code, Args...)>+  : public co_composed_handler_base<Executors, Handler, Return>+{+public:+  using co_composed_handler_base<Executors,+    Handler, Return>::co_composed_handler_base;++  using args_type = std::tuple<typename decay<Args>::type...>;+  using result_type = std::tuple<asio::error_code, args_type>;++  template <typename... T>+  void operator()(const asio::error_code& ec, T&&... args)+  {+    result_type result(ec, args_type(std::forward<T>(args)...));+    this->resume(&result);+  }++  static auto on_resume(void* result)+  {+    auto& [ec, args] = *static_cast<result_type*>(result);+    throw_error(ec);+    if constexpr (sizeof...(Args) == 0)+      return;+    else if constexpr (sizeof...(Args) == 1)+      return std::move(std::get<0>(args));+    else+      return std::move(args);+  }+};++template <typename Executors, typename Handler,+    typename Return, typename R, typename... Args>+class co_composed_handler<Executors, Handler,+    Return, R(std::exception_ptr, Args...)>+  : public co_composed_handler_base<Executors, Handler, Return>+{+public:+  using co_composed_handler_base<Executors,+    Handler, Return>::co_composed_handler_base;++  using args_type = std::tuple<typename decay<Args>::type...>;+  using result_type = std::tuple<std::exception_ptr, args_type>;++  template <typename... T>+  void operator()(std::exception_ptr ex, T&&... args)+  {+    result_type result(std::move(ex), args_type(std::forward<T>(args)...));+    this->resume(&result);+  }++  static auto on_resume(void* result)+  {+    auto& [ex, args] = *static_cast<result_type*>(result);+    if (ex)+      std::rethrow_exception(ex);+    if constexpr (sizeof...(Args) == 0)+      return;+    else if constexpr (sizeof...(Args) == 1)+      return std::move(std::get<0>(args));+    else+      return std::move(args);+  }+};++template <typename Executors, typename Handler, typename Return>+class co_composed_promise_return;++template <typename Executors, typename Handler>+class co_composed_promise_return<Executors, Handler, co_composed_returns<>>+{+public:+  auto final_suspend() noexcept+  {+    return suspend_never();+  }++  void return_void() noexcept+  {+  }+};++template <typename Executors, typename Handler,+    typename Return, typename Signature>+class co_composed_promise_return_overload;++template <typename Executors, typename Handler,+    typename Return, typename R, typename... Args>+class co_composed_promise_return_overload<+    Executors, Handler, Return, R(Args...)>+{+public:+  using derived_type = co_composed_promise<Executors, Handler, Return>;+  using return_type = std::tuple<Args...>;++  void return_value(std::tuple<Args...>&& value)+  {+    derived_type& promise = *static_cast<derived_type*>(this);+    promise.state().return_value_ = std::move(value);+    promise.state().work_.reset();+    promise.state().on_suspend_->arg_ = this;+    promise.state().on_suspend_->fn_ =+      [](void* p)+      {+        auto& promise = *static_cast<derived_type*>(p);++        co_composed_handler_base<Executors, Handler,+          Return> composed_handler(promise);++        Handler handler(std::move(promise.state().handler_));+        return_type result(+            std::move(std::get<return_type>(promise.state().return_value_)));++        co_composed_handler_base<Executors, Handler,+          Return>(std::move(composed_handler));++        std::apply(std::move(handler), std::move(result));+      };+  }+};++template <typename Executors, typename Handler, typename... Signatures>+class co_composed_promise_return<Executors,+    Handler, co_composed_returns<Signatures...>>+  : public co_composed_promise_return_overload<Executors,+      Handler, co_composed_returns<Signatures...>, Signatures>...+{+public:+  auto final_suspend() noexcept+  {+    return suspend_always();+  }++  using co_composed_promise_return_overload<Executors, Handler,+    co_composed_returns<Signatures...>, Signatures>::return_value...;++private:+  template <typename, typename, typename, typename>+    friend class co_composed_promise_return_overload;+};++template <typename Executors, typename Handler, typename Return>+class co_composed_promise+  : public co_composed_promise_return<Executors, Handler, Return>+{+public:+  template <typename... Args>+  void* operator new(std::size_t size,+      co_composed_state<Executors, Handler, Return>& state, Args&&...)+  {+    block_allocator_type allocator(+      (get_associated_allocator)(state.handler_,+        recycling_allocator<void>()));++    block* base_ptr = std::allocator_traits<block_allocator_type>::allocate(+        allocator, blocks(sizeof(allocator_type)) + blocks(size));++    new (static_cast<void*>(base_ptr)) allocator_type(std::move(allocator));++    return base_ptr + blocks(sizeof(allocator_type));+  }++  template <typename C, typename... Args>+  void* operator new(std::size_t size, C&&,+      co_composed_state<Executors, Handler, Return>& state, Args&&...)+  {+    return co_composed_promise::operator new(size, state);+  }++  void operator delete(void* ptr, std::size_t size)+  {+    block* base_ptr = static_cast<block*>(ptr) - blocks(sizeof(allocator_type));++    allocator_type* allocator_ptr = std::launder(+        static_cast<allocator_type*>(static_cast<void*>(base_ptr)));++    block_allocator_type block_allocator(std::move(*allocator_ptr));+    allocator_ptr->~allocator_type();++    std::allocator_traits<block_allocator_type>::deallocate(block_allocator,+        base_ptr, blocks(sizeof(allocator_type)) + blocks(size));+  }++  template <typename... Args>+  co_composed_promise(+      co_composed_state<Executors, Handler, Return>& state, Args&&...)+    : state_(state)+  {+  }++  template <typename C, typename... Args>+  co_composed_promise(C&&,+      co_composed_state<Executors, Handler, Return>& state, Args&&...)+    : state_(state)+  {+  }++  void destroy() noexcept+  {+    coroutine_handle<co_composed_promise>::from_promise(*this).destroy();+  }++  void resume(co_composed_promise*& owner, void* result,+      co_composed_on_suspend& on_suspend)+  {+    state_.on_suspend_ = &on_suspend;+    state_.clear_cancellation_slot();+    owner_ = &owner;+    result_ = result;+    coroutine_handle<co_composed_promise>::from_promise(*this).resume();+  }++  co_composed_state<Executors, Handler, Return>& state() noexcept+  {+    return state_;+  }++  void get_return_object() noexcept+  {+  }++  auto initial_suspend() noexcept+  {+    return suspend_never();+  }++  void unhandled_exception()+  {+    if (owner_)+      *owner_ = this;+    throw;+  }++  template <async_operation Op>+  auto await_transform(Op&& op+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+      , asio::detail::source_location location+        = asio::detail::source_location::current()+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+    )+  {+    class [[nodiscard]] awaitable+    {+    public:+      awaitable(Op&& op, co_composed_promise& promise+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+          , const asio::detail::source_location& location+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+        )+        : op_(std::forward<Op>(op)),+          promise_(promise)+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+        , location_(location)+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+      {+      }++      constexpr bool await_ready() const noexcept+      {+        return false;+      }++      void await_suspend(coroutine_handle<co_composed_promise>)+      {+        if (promise_.state_.check_for_cancellation_on_suspend(promise_))+        {+          promise_.state_.on_suspend_->arg_ = this;+          promise_.state_.on_suspend_->fn_ =+            [](void* p)+            {+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+              ASIO_HANDLER_LOCATION((+                  static_cast<awaitable*>(p)->location_.file_name(),+                  static_cast<awaitable*>(p)->location_.line(),+                  static_cast<awaitable*>(p)->location_.function_name()));+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+              std::forward<Op>(static_cast<awaitable*>(p)->op_)(+                  co_composed_handler<Executors, Handler,+                    Return, completion_signature_of_t<Op>>(+                      static_cast<awaitable*>(p)->promise_));+            };+        }+      }++      auto await_resume()+      {+        return co_composed_handler<Executors, Handler, Return,+          completion_signature_of_t<Op>>::on_resume(promise_.result_);+      }++    private:+      Op&& op_;+      co_composed_promise& promise_;+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+      asio::detail::source_location location_;+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+    };++    state_.check_for_cancellation_on_transform();+    return awaitable{std::forward<Op>(op), *this+#if defined(ASIO_ENABLE_HANDLER_TRACKING)+# if defined(ASIO_HAS_SOURCE_LOCATION)+        , location+# endif // defined(ASIO_HAS_SOURCE_LOCATION)+#endif // defined(ASIO_ENABLE_HANDLER_TRACKING)+      };+  }++  template <typename... Args>+  auto yield_value(co_composed_completion<Args...>&& result)+  {+    class [[nodiscard]] awaitable+    {+    public:+      awaitable(co_composed_completion<Args...>&& result,+          co_composed_promise& promise)+        : result_(std::move(result)),+          promise_(promise)+      {+      }++      constexpr bool await_ready() const noexcept+      {+        return false;+      }++      void await_suspend(coroutine_handle<co_composed_promise>)+      {+        promise_.state_.work_.reset();+        promise_.state_.on_suspend_->arg_ = this;+        promise_.state_.on_suspend_->fn_ =+          [](void* p)+          {+            awaitable& a = *static_cast<awaitable*>(p);++            co_composed_handler_base<Executors, Handler,+              Return> composed_handler(a.promise_);++            Handler handler(std::move(a.promise_.state_.handler_));+            std::tuple<typename decay<Args>::type...> result(+                std::move(static_cast<std::tuple<Args&&...>>(a.result_)));++            co_composed_handler_base<Executors, Handler,+              Return>(std::move(composed_handler));++            std::apply(std::move(handler), std::move(result));+          };+      }++      void await_resume() noexcept+      {+      }++    private:+      co_composed_completion<Args...> result_;+      co_composed_promise& promise_;+    };++    return awaitable{std::move(result), *this};+  }++private:+  using allocator_type =+    associated_allocator_t<Handler, recycling_allocator<void>>;++  union block+  {+    std::max_align_t max_align;+    alignas(allocator_type) char pad[alignof(allocator_type)];+  };++  using block_allocator_type =+    typename std::allocator_traits<allocator_type>+      ::template rebind_alloc<block>;++  static constexpr std::size_t blocks(std::size_t size)+  {+    return (size + sizeof(block) - 1) / sizeof(block);+  }++  co_composed_state<Executors, Handler, Return>& state_;+  co_composed_promise** owner_ = nullptr;+  void* result_ = nullptr;+};++template <typename Implementation, typename Executors, typename... Signatures>+class initiate_co_composed+{+public:+  using executor_type = typename composed_io_executors<Executors>::head_type;++  template <typename I>+  initiate_co_composed(I&& impl, composed_io_executors<Executors>&& executors)+    : implementation_(std::forward<I>(impl)),+      executors_(std::move(executors))+  {+  }++  executor_type get_executor() const noexcept+  {+    return executors_.head_;+  }++  template <typename Handler, typename... InitArgs>+  void operator()(Handler&& handler, InitArgs&&... init_args) const &+  {+    using handler_type = typename decay<Handler>::type;+    using returns_type = co_composed_returns<Signatures...>;+    co_composed_on_suspend on_suspend{};+    implementation_(+        co_composed_state<Executors, handler_type, returns_type>(+          executors_, std::forward<Handler>(handler), on_suspend),+        std::forward<InitArgs>(init_args)...);+    if (on_suspend.fn_)+      on_suspend.fn_(on_suspend.arg_);+  }++  template <typename Handler, typename... InitArgs>+  void operator()(Handler&& handler, InitArgs&&... init_args) &&+  {+    using handler_type = typename decay<Handler>::type;+    using returns_type = co_composed_returns<Signatures...>;+    co_composed_on_suspend on_suspend{};+    std::move(implementation_)(+        co_composed_state<Executors, handler_type, returns_type>(+          std::move(executors_), std::forward<Handler>(handler), on_suspend),+        std::forward<InitArgs>(init_args)...);+    if (on_suspend.fn_)+      on_suspend.fn_(on_suspend.arg_);+  }++private:+  Implementation implementation_;+  composed_io_executors<Executors> executors_;+};++template <typename... Signatures, typename Implementation, typename Executors>+inline initiate_co_composed<Implementation, Executors, Signatures...>+make_initiate_co_composed(Implementation&& implementation,+    composed_io_executors<Executors>&& executors)+{+  return initiate_co_composed<+    typename decay<Implementation>::type, Executors, Signatures...>(+        std::forward<Implementation>(implementation), std::move(executors));+}++} // namespace detail++template <completion_signature... Signatures,+    typename Implementation, typename... IoObjectsOrExecutors>+inline auto co_composed(Implementation&& implementation,+    IoObjectsOrExecutors&&... io_objects_or_executors)+{+  return detail::make_initiate_co_composed<Signatures...>(+      std::forward<Implementation>(implementation),+      detail::make_composed_io_executors(+        detail::get_composed_io_executor(+          std::forward<IoObjectsOrExecutors>(+            io_objects_or_executors))...));+}++} // namespace experimental++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename Executors, typename Handler, typename Return,+    typename Signature, typename DefaultCandidate>+struct associator<Associator,+    experimental::detail::co_composed_handler<+      Executors, Handler, Return, Signature>,+    DefaultCandidate>+  : Associator<Handler, DefaultCandidate>+{+  static typename Associator<Handler, DefaultCandidate>::type+  get(const experimental::detail::co_composed_handler<+        Executors, Handler, Return, Signature>& h) ASIO_NOEXCEPT+  {+    return Associator<Handler, DefaultCandidate>::get(+        h.promise().state().handler());+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const experimental::detail::co_composed_handler<+        Executors, Handler, Return, Signature>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(+        h.promise().state().handler(), c)))+  {+    return Associator<Handler, DefaultCandidate>::get(+        h.promise().state().handler(), c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++} // namespace asio++#if !defined(GENERATING_DOCUMENTATION)+# if defined(ASIO_HAS_STD_COROUTINE)+namespace std {+# else // defined(ASIO_HAS_STD_COROUTINE)+namespace std { namespace experimental {+# endif // defined(ASIO_HAS_STD_COROUTINE)++template <typename C, typename Executors,+    typename Handler, typename Return, typename... Args>+struct coroutine_traits<void, C&,+    asio::experimental::detail::co_composed_state<+      Executors, Handler, Return>,+    Args...>+{+  using promise_type =+    asio::experimental::detail::co_composed_promise<+      Executors, Handler, Return>;+};++template <typename C, typename Executors,+    typename Handler, typename Return, typename... Args>+struct coroutine_traits<void, C&&,+    asio::experimental::detail::co_composed_state<+      Executors, Handler, Return>,+    Args...>+{+  using promise_type =+    asio::experimental::detail::co_composed_promise<+      Executors, Handler, Return>;+};++template <typename Executors, typename Handler,+    typename Return, typename... Args>+struct coroutine_traits<void,+    asio::experimental::detail::co_composed_state<+      Executors, Handler, Return>,+    Args...>+{+  using promise_type =+    asio::experimental::detail::co_composed_promise<+      Executors, Handler, Return>;+};++# if defined(ASIO_HAS_STD_COROUTINE)+} // namespace std+# else // defined(ASIO_HAS_STD_COROUTINE)+}} // namespace std::experimental+# endif // defined(ASIO_HAS_STD_COROUTINE)+#endif // !defined(GENERATING_DOCUMENTATION)++#include "asio/detail/pop_options.hpp"++#endif // ASIO_IMPL_EXPERIMENTAL_CO_COMPOSED_HPP
link/modules/asio-standalone/asio/include/asio/experimental/impl/coro.hpp view
@@ -45,18 +45,18 @@   }    template <typename Filter>-  void reset_cancellation_state(Filter&& filter)+  void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter)   {-    state = cancellation_state(slot, static_cast<Filter&&>(filter));+    state = cancellation_state(slot, ASIO_MOVE_CAST(Filter)(filter));   }    template <typename InFilter, typename OutFilter>-  void reset_cancellation_state(InFilter&& in_filter,-      OutFilter&& out_filter)+  void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,+      ASIO_MOVE_ARG(OutFilter) out_filter)   {     state = cancellation_state(slot,-        static_cast<InFilter&&>(in_filter),-        static_cast<OutFilter&&>(out_filter));+        ASIO_MOVE_CAST(InFilter)(in_filter),+        ASIO_MOVE_CAST(OutFilter)(out_filter));   }    bool throw_if_cancelled() const@@ -600,7 +600,7 @@    cancellation_slot_type get_cancellation_slot() const noexcept   {-    return cancel ? cancel->state.slot() : cancellation_slot_type{};+    return cancel ? cancel->slot : cancellation_slot_type{};   }    using allocator_type =@@ -767,11 +767,11 @@       auto await_resume()       {         return src_->reset_cancellation_state(-            static_cast<Filter&&>(filter_));+            ASIO_MOVE_CAST(Filter)(filter_));       }     }; -    return result{cancel, static_cast<Filter&&>(reset.filter)};+    return result{cancel, ASIO_MOVE_CAST(Filter)(reset.filter)};   }    // This await transformation resets the associated cancellation state.@@ -798,14 +798,14 @@       auto await_resume()       {         return src_->reset_cancellation_state(-            static_cast<InFilter&&>(in_filter_),-            static_cast<OutFilter&&>(out_filter_));+            ASIO_MOVE_CAST(InFilter)(in_filter_),+            ASIO_MOVE_CAST(OutFilter)(out_filter_));       }     };      return result{cancel,-        static_cast<InFilter&&>(reset.in_filter),-        static_cast<OutFilter&&>(reset.out_filter)};+        ASIO_MOVE_CAST(InFilter)(reset.in_filter),+        ASIO_MOVE_CAST(OutFilter)(reset.out_filter)};   }    // This await transformation determines whether cancellation is propagated as@@ -894,7 +894,7 @@    template <typename Op>   auto await_transform(Op&& op,-      constraint_t<is_async_operation<Op>::value> = 0)+      typename constraint<is_async_operation<Op>::value>::type = 0)   {     if ((cancel->state.cancelled() != cancellation_type::none)         && cancel->throw_if_cancelled_)@@ -902,7 +902,7 @@       asio::detail::throw_error(           asio::error::operation_aborted, "coro-cancelled");     }-    using signature = completion_signature_of_t<Op>;+    using signature = typename completion_signature_of<Op>::type;     using result_type = detail::coro_completion_handler_type_t<signature>;     using handler_type =       typename detail::coro_completion_handler_type<signature>::template@@ -1069,17 +1069,17 @@       std::true_type /* error is noexcept */,       std::true_type /* result is void */)  //noexcept   {-    return [this, the_coro = coro_,+    return [this, coro = coro_,         h = std::forward<WaitHandler>(handler),         exec = std::move(exec)]() mutable     {-      assert(the_coro);+      assert(coro); -      auto ch = detail::coroutine_handle<promise_type>::from_promise(*the_coro);+      auto ch = detail::coroutine_handle<promise_type>::from_promise(*coro);       assert(ch && !ch.done()); -      the_coro->awaited_from = post_coroutine(std::move(exec), std::move(h));-      the_coro->reset_error();+      coro->awaited_from = post_coroutine(std::move(exec), std::move(h));+      coro->reset_error();       ch.resume();     };   }@@ -1090,18 +1090,18 @@       std::true_type /* error is noexcept */,       std::false_type  /* result is void */)  //noexcept   {-    return [the_coro = coro_,+    return [coro = coro_,         h = std::forward<WaitHandler>(handler),         exec = std::move(exec)]() mutable     {-      assert(the_coro);+      assert(coro); -      auto ch = detail::coroutine_handle<promise_type>::from_promise(*the_coro);+      auto ch = detail::coroutine_handle<promise_type>::from_promise(*coro);       assert(ch && !ch.done()); -      the_coro->awaited_from = detail::post_coroutine(-          exec, std::move(h), the_coro->result_).handle;-      the_coro->reset_error();+      coro->awaited_from = detail::post_coroutine(+          exec, std::move(h), coro->result_).handle;+      coro->reset_error();       ch.resume();     };   }@@ -1111,16 +1111,16 @@       std::false_type /* error is noexcept */,       std::true_type /* result is void */)   {-    return [the_coro = coro_,+    return [coro = coro_,         h = std::forward<WaitHandler>(handler),         exec = std::move(exec)]() mutable     {-      if (!the_coro)+      if (!coro)         return asio::post(exec,             asio::append(std::move(h),               detail::coro_error<error_type>::invalid())); -      auto ch = detail::coroutine_handle<promise_type>::from_promise(*the_coro);+      auto ch = detail::coroutine_handle<promise_type>::from_promise(*coro);       if (!ch)         return asio::post(exec,             asio::append(std::move(h),@@ -1131,9 +1131,9 @@               detail::coro_error<error_type>::done()));       else       {-        the_coro->awaited_from = detail::post_coroutine(-            exec, std::move(h), the_coro->error_).handle;-        the_coro->reset_error();+        coro->awaited_from = detail::post_coroutine(+            exec, std::move(h), coro->error_).handle;+        coro->reset_error();         ch.resume();       }     };@@ -1144,17 +1144,17 @@       std::false_type /* error is noexcept */,       std::false_type  /* result is void */)   {-    return [the_coro = coro_,+    return [coro = coro_,         h = std::forward<WaitHandler>(handler),         exec = std::move(exec)]() mutable     {-      if (!the_coro)+      if (!coro)         return asio::post(exec,             asio::append(std::move(h),               detail::coro_error<error_type>::invalid(), result_type{}));        auto ch =-        detail::coroutine_handle<promise_type>::from_promise(*the_coro);+        detail::coroutine_handle<promise_type>::from_promise(*coro);       if (!ch)         return asio::post(exec,             asio::append(std::move(h),@@ -1165,9 +1165,9 @@               detail::coro_error<error_type>::done(), result_type{}));       else       {-        the_coro->awaited_from = detail::post_coroutine(-            exec, std::move(h), the_coro->error_, the_coro->result_).handle;-        the_coro->reset_error();+        coro->awaited_from = detail::post_coroutine(+            exec, std::move(h), coro->error_, coro->result_).handle;+        coro->reset_error();         ch.resume();       }     };@@ -1203,9 +1203,9 @@         [h = handle(exec, std::forward<WaitHandler>(handler),             std::integral_constant<bool, is_noexcept>{},             std::is_void<result_type>{}),-            in = std::forward<Input>(input), the_coro = coro_]() mutable+            in = std::forward<Input>(input), coro = coro_]() mutable         {-          the_coro->input_ = std::move(in);+          coro->input_ = std::move(in);           std::move(h)();         });   }
link/modules/asio-standalone/asio/include/asio/experimental/impl/parallel_group.hpp view
@@ -2,7 +2,7 @@ // experimental/impl/parallel_group.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -78,18 +78,18 @@   bool has_value_; }; -// Proxy completion handler for the group of parallel operations. Unpacks and+// Proxy completion handler for the group of parallel operatations. Unpacks and // concatenates the individual operations' results, and invokes the user's // completion handler. template <typename Handler, typename... Ops> struct parallel_group_completion_handler {-  typedef decay_t<-      prefer_result_t<-        associated_executor_t<Handler>,+  typedef typename decay<+      typename prefer_result<+        typename associated_executor<Handler>::type,         execution::outstanding_work_t::tracked_t-      >-    > executor_type;+      >::type+    >::type executor_type;    parallel_group_completion_handler(Handler&& h)     : handler_(std::move(h)),@@ -136,7 +136,7 @@   std::tuple<       parallel_group_op_result<         typename parallel_op_signature_as_tuple<-          completion_signature_of_t<Ops>+          typename completion_signature_of<Ops>::type         >::type       >...     > args_{};@@ -189,7 +189,7 @@   typedef asio::cancellation_slot cancellation_slot_type;    parallel_group_op_handler(-    std::shared_ptr<parallel_group_state<Condition, Handler, Ops...>> state)+    std::shared_ptr<parallel_group_state<Condition, Handler, Ops...> > state)     : state_(std::move(state))   {   }@@ -230,7 +230,7 @@       asio::dispatch(std::move(state_->handler_));   } -  std::shared_ptr<parallel_group_state<Condition, Handler, Ops...>> state_;+  std::shared_ptr<parallel_group_state<Condition, Handler, Ops...> > state_; };  // Handler for an individual operation within the parallel group that has an@@ -245,7 +245,7 @@   typedef Executor executor_type;    parallel_group_op_handler_with_executor(-      std::shared_ptr<parallel_group_state<Condition, Handler, Ops...>> state,+      std::shared_ptr<parallel_group_state<Condition, Handler, Ops...> > state,       executor_type ex)     : parallel_group_op_handler<I, Condition, Handler, Ops...>(std::move(state))   {@@ -269,7 +269,7 @@   {     cancel_proxy(         std::shared_ptr<parallel_group_state<-          Condition, Handler, Ops...>> state,+          Condition, Handler, Ops...> > state,         executor_type ex)       : state_(std::move(state)),         executor_(std::move(ex))@@ -286,7 +286,7 @@       }     } -    std::weak_ptr<parallel_group_state<Condition, Handler, Ops...>> state_;+    std::weak_ptr<parallel_group_state<Condition, Handler, Ops...> > state_;     asio::cancellation_signal signal_;     executor_type executor_;   };@@ -301,9 +301,9 @@   template <typename Condition, typename Handler, typename... Ops>   static void launch(Op& op,     const std::shared_ptr<parallel_group_state<-      Condition, Handler, Ops...>>& state)+      Condition, Handler, Ops...> >& state)   {-    typedef associated_executor_t<Op> ex_type;+    typedef typename associated_executor<Op>::type ex_type;     ex_type ex = asio::get_associated_executor(op);     std::move(op)(         parallel_group_op_handler_with_executor<ex_type, I,@@ -314,18 +314,18 @@ // Specialised launcher for operations that specify no executor. template <std::size_t I, typename Op> struct parallel_group_op_launcher<I, Op,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_executor<           Op>::asio_associated_executor_is_unspecialised,         void       >::value-    >>+    >::type> {   template <typename Condition, typename Handler, typename... Ops>   static void launch(Op& op,     const std::shared_ptr<parallel_group_state<-      Condition, Handler, Ops...>>& state)+      Condition, Handler, Ops...> >& state)   {     std::move(op)(         parallel_group_op_handler<I, Condition, Handler, Ops...>(state));@@ -336,7 +336,7 @@ struct parallel_group_cancellation_handler {   parallel_group_cancellation_handler(-    std::shared_ptr<parallel_group_state<Condition, Handler, Ops...>> state)+    std::shared_ptr<parallel_group_state<Condition, Handler, Ops...> > state)     : state_(std::move(state))   {   }@@ -353,7 +353,7 @@             state->cancellation_signals_[i].emit(cancel_type);   } -  std::weak_ptr<parallel_group_state<Condition, Handler, Ops...>> state_;+  std::weak_ptr<parallel_group_state<Condition, Handler, Ops...> > state_; };  template <typename Condition, typename Handler,@@ -363,7 +363,7 @@ {   // Get the user's completion handler's cancellation slot, so that we can allow   // cancellation of the entire group.-  associated_cancellation_slot_t<Handler> slot+  typename associated_cancellation_slot<Handler>::type slot     = asio::get_associated_cancellation_slot(handler);    // Create the shared state for the operation.@@ -390,24 +390,24 @@   if (slot.is_connected())     slot.template emplace<       parallel_group_cancellation_handler<-        Condition, Handler, Ops...>>(state);+        Condition, Handler, Ops...> >(state); } -// Proxy completion handler for the ranged group of parallel operations.+// Proxy completion handler for the ranged group of parallel operatations. // Unpacks and recombines the individual operations' results, and invokes the // user's completion handler. template <typename Handler, typename Op, typename Allocator> struct ranged_parallel_group_completion_handler {-  typedef decay_t<-      prefer_result_t<-        associated_executor_t<Handler>,+  typedef typename decay<+      typename prefer_result<+        typename associated_executor<Handler>::type,         execution::outstanding_work_t::tracked_t-      >-    > executor_type;+      >::type+    >::type executor_type;    typedef typename parallel_op_signature_as_tuple<-      completion_signature_of_t<Op>+      typename completion_signature_of<Op>::type     >::type op_tuple_type;    typedef parallel_group_op_result<op_tuple_type> op_result_type;@@ -445,7 +445,7 @@   {     typedef typename parallel_op_signature_as_tuple<         typename ranged_parallel_group_signature<-          completion_signature_of_t<Op>,+          typename completion_signature_of<Op>::type,           Allocator         >::raw_type       >::type vectors_type;@@ -473,8 +473,7 @@       (void)pushback_fold;     } -    std::move(handler_)(std::move(completion_order_),-        std::move(std::get<I>(vectors))...);+    std::move(handler_)(completion_order_, std::move(std::get<I>(vectors))...);   }    Handler handler_;@@ -544,7 +543,7 @@    ranged_parallel_group_op_handler(       std::shared_ptr<ranged_parallel_group_state<-        Condition, Handler, Op, Allocator>> state,+        Condition, Handler, Op, Allocator> > state,       std::size_t idx)     : state_(std::move(state)),       idx_(idx)@@ -588,7 +587,7 @@   }    std::shared_ptr<ranged_parallel_group_state<-    Condition, Handler, Op, Allocator>> state_;+    Condition, Handler, Op, Allocator> > state_;   std::size_t idx_; }; @@ -606,7 +605,7 @@    ranged_parallel_group_op_handler_with_executor(       std::shared_ptr<ranged_parallel_group_state<-        Condition, Handler, Op, Allocator>> state,+        Condition, Handler, Op, Allocator> > state,       executor_type ex, std::size_t idx)     : ranged_parallel_group_op_handler<Condition, Handler, Op, Allocator>(         std::move(state), idx)@@ -631,7 +630,7 @@   {     cancel_proxy(         std::shared_ptr<ranged_parallel_group_state<-          Condition, Handler, Op, Allocator>> state,+          Condition, Handler, Op, Allocator> > state,         executor_type ex)       : state_(std::move(state)),         executor_(std::move(ex))@@ -649,7 +648,7 @@     }      std::weak_ptr<ranged_parallel_group_state<-      Condition, Handler, Op, Allocator>> state_;+      Condition, Handler, Op, Allocator> > state_;     asio::cancellation_signal signal_;     executor_type executor_;   };@@ -662,7 +661,7 @@ {   ranged_parallel_group_cancellation_handler(       std::shared_ptr<ranged_parallel_group_state<-        Condition, Handler, Op, Allocator>> state)+        Condition, Handler, Op, Allocator> > state)     : state_(std::move(state))   {   }@@ -680,7 +679,7 @@   }    std::weak_ptr<ranged_parallel_group_state<-    Condition, Handler, Op, Allocator>> state_;+    Condition, Handler, Op, Allocator> > state_; };  template <typename Condition, typename Handler,@@ -690,11 +689,12 @@ {   // Get the user's completion handler's cancellation slot, so that we can allow   // cancellation of the entire group.-  associated_cancellation_slot_t<Handler> slot-    = asio::get_associated_cancellation_slot(handler);+  typename associated_cancellation_slot<Handler>::type slot+          = asio::get_associated_cancellation_slot(handler);    // The type of the asynchronous operation.-  typedef decay_t<decltype(*declval<typename Range::iterator>())> op_type;+  typedef typename std::decay<decltype(+      *std::declval<typename Range::iterator>())>::type op_type;    // Create the shared state for the operation.   typedef ranged_parallel_group_state<Condition,@@ -706,10 +706,9 @@       std::move(handler), range.size(), allocator);    std::size_t idx = 0;-  std::size_t range_size = range.size();   for (auto&& op : std::forward<Range>(range))   {-    typedef associated_executor_t<op_type> ex_type;+    typedef typename associated_executor<op_type>::type ex_type;     ex_type ex = asio::get_associated_executor(op);     std::move(op)(         ranged_parallel_group_op_handler_with_executor<@@ -719,7 +718,7 @@    // Check if any of the operations has already requested cancellation, and if   // so, emit a signal for each operation in the group.-  if ((state->cancellations_requested_ -= range_size) > 0)+  if ((state->cancellations_requested_ -= range.size()) > 0)     for (auto& signal : state->cancellation_signals_)       signal.emit(state->cancel_type_); @@ -727,7 +726,7 @@   if (slot.is_connected())     slot.template emplace<       ranged_parallel_group_cancellation_handler<-        Condition, Handler, op_type, Allocator>>(state);+        Condition, Handler, op_type, Allocator> >(state); }  } // namespace detail@@ -740,18 +739,20 @@     DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const experimental::detail::parallel_group_completion_handler<-        Handler, Ops...>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const experimental::detail::parallel_group_completion_handler<+        Handler, Ops...>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const experimental::detail::parallel_group_completion_handler<+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const experimental::detail::parallel_group_completion_handler<         Handler, Ops...>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }@@ -765,18 +766,20 @@     DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const experimental::detail::ranged_parallel_group_completion_handler<-        Handler, Op, Allocator>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const experimental::detail::ranged_parallel_group_completion_handler<+        Handler, Op, Allocator>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const experimental::detail::ranged_parallel_group_completion_handler<+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const experimental::detail::ranged_parallel_group_completion_handler<         Handler, Op, Allocator>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }
link/modules/asio-standalone/asio/include/asio/experimental/impl/promise.hpp view
@@ -18,8 +18,6 @@ #include "asio/detail/config.hpp" #include "asio/cancellation_signal.hpp" #include "asio/detail/utility.hpp"-#include "asio/error.hpp"-#include "asio/system_error.hpp" #include <tuple>  #include "asio/detail/push_options.hpp"@@ -58,7 +56,8 @@       reinterpret_cast<result_type*>(&result)->~result_type();   } -  aligned_storage_t<sizeof(result_type), alignof(result_type)> result;+  typename aligned_storage<sizeof(result_type),+    alignof(result_type)>::type result;   std::atomic<bool> done{false};   cancellation_signal cancel;   Allocator allocator;@@ -187,7 +186,7 @@  template<typename Signature = void(),     typename Executor = asio::any_io_executor,-    typename Allocator = std::allocator<void>>+    typename Allocator = any_io_executor> struct promise_handler;  template<typename... Ts,  typename Executor, typename Allocator>
link/modules/asio-standalone/asio/include/asio/experimental/impl/use_promise.hpp view
@@ -44,11 +44,11 @@   template <typename Initiation, typename... InitArgs>   static auto initiate(Initiation initiation,       experimental::use_promise_t<Allocator> up, InitArgs... args)-    -> experimental::promise<void(decay_t<Args>...),+    -> experimental::promise<void(typename decay<Args>::type...),       asio::associated_executor_t<Initiation>, Allocator>   {     using handler_type = experimental::detail::promise_handler<-      void(decay_t<Args>...),+      void(typename decay<Args>::type...),       asio::associated_executor_t<Initiation>, Allocator>;      handler_type ht{up.get_allocator(), get_associated_executor(initiation)};
link/modules/asio-standalone/asio/include/asio/experimental/parallel_group.hpp view
@@ -2,7 +2,7 @@ // experimental/parallel_group.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,10 +17,8 @@  #include "asio/detail/config.hpp" #include <vector>-#include "asio/async_result.hpp" #include "asio/detail/array.hpp" #include "asio/detail/memory.hpp"-#include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp" #include "asio/experimental/cancellation_condition.hpp" @@ -38,7 +36,7 @@ template <typename R, typename... Args> struct parallel_op_signature_as_tuple<R(Args...)> {-  typedef std::tuple<decay_t<Args>...> type;+  typedef std::tuple<typename decay<Args>::type...> type; };  // Helper trait for concatenating completion signatures.@@ -164,7 +162,7 @@    /// The completion signature for the group of operations.   typedef typename detail::parallel_group_signature<sizeof...(Ops),-      completion_signature_of_t<Ops>...>::type signature;+      typename completion_signature_of<Ops>::type...>::type signature;    /// Initiate an asynchronous wait for the group of operations.   /**@@ -190,12 +188,13 @@    */   template <typename CancellationCondition,       ASIO_COMPLETION_TOKEN_FOR(signature) CompletionToken>-  auto async_wait(CancellationCondition cancellation_condition,+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, signature)+  async_wait(CancellationCondition cancellation_condition,       CompletionToken&& token)-    -> decltype(+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       asio::async_initiate<CompletionToken, signature>(-        declval<initiate_async_wait>(), token,-        std::move(cancellation_condition), std::move(ops_)))+          declval<initiate_async_wait>(), token,+          std::move(cancellation_condition), std::move(ops_))))   {     return asio::async_initiate<CompletionToken, signature>(         initiate_async_wait(), token,@@ -207,36 +206,6 @@ /**  * For example:  * @code asio::experimental::make_parallel_group(- *    in.async_read_some(asio::buffer(data)),- *    timer.async_wait()- *  ).async_wait(- *    asio::experimental::wait_for_all(),- *    [](- *        std::array<std::size_t, 2> completion_order,- *        std::error_code ec1, std::size_t n1,- *        std::error_code ec2- *    )- *    {- *      switch (completion_order[0])- *      {- *      case 0:- *        {- *          std::cout << "descriptor finished: " << ec1 << ", " << n1 << "\n";- *        }- *        break;- *      case 1:- *        {- *          std::cout << "timer finished: " << ec2 << "\n";- *        }- *        break;- *      }- *    }- *  );- * @endcode- *- * If preferred, the asynchronous operations may be explicitly packaged as- * function objects:- * @code asio::experimental::make_parallel_group(  *    [&](auto token)  *    {  *      return in.async_read_some(asio::buffer(data), token);@@ -283,7 +252,7 @@  * See the documentation for asio::experimental::make_parallel_group for  * a usage example.  */-template <typename Range, typename Allocator = std::allocator<void>>+template <typename Range, typename Allocator = std::allocator<void> > class ranged_parallel_group { private:@@ -312,8 +281,9 @@    /// The completion signature for the group of operations.   typedef typename detail::ranged_parallel_group_signature<-      completion_signature_of_t<-        decay_t<decltype(*std::declval<typename Range::iterator>())>>,+      typename completion_signature_of<+        typename std::decay<+          decltype(*std::declval<typename Range::iterator>())>::type>::type,       Allocator>::type signature;    /// Initiate an asynchronous wait for the group of operations.@@ -341,13 +311,14 @@    */   template <typename CancellationCondition,       ASIO_COMPLETION_TOKEN_FOR(signature) CompletionToken>-  auto async_wait(CancellationCondition cancellation_condition,+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, signature)+  async_wait(CancellationCondition cancellation_condition,       CompletionToken&& token)-    -> decltype(+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       asio::async_initiate<CompletionToken, signature>(-        declval<initiate_async_wait>(), token,-        std::move(cancellation_condition),-        std::move(range_), allocator_))+          declval<initiate_async_wait>(), token,+          std::move(cancellation_condition),+          std::move(range_), allocator_)))   {     return asio::async_initiate<CompletionToken, signature>(         initiate_async_wait(), token,@@ -362,13 +333,29 @@  *  * For example:  * @code- * using op_type =- *   decltype(socket1.async_read_some(asio::buffer(data1)));+ * using op_type = decltype(+ *     socket1.async_read_some(+ *       asio::buffer(data1),+ *       asio::deferred+ *     )+ *   );  *  * std::vector<op_type> ops;- * ops.push_back(socket1.async_read_some(asio::buffer(data1)));- * ops.push_back(socket2.async_read_some(asio::buffer(data2)));  *+ * ops.push_back(+ *     socket1.async_read_some(+ *       asio::buffer(data1),+ *       asio::deferred+ *     )+ *   );+ *+ * ops.push_back(+ *     socket2.async_read_some(+ *       asio::buffer(data2),+ *       asio::deferred+ *     )+ *   );+ *  * asio::experimental::make_parallel_group(ops).async_wait(  *     asio::experimental::wait_for_all(),  *     [](@@ -388,13 +375,15 @@  * @endcode  */ template <typename Range>-ASIO_NODISCARD inline ranged_parallel_group<decay_t<Range>>+ASIO_NODISCARD inline+ranged_parallel_group<typename std::decay<Range>::type> make_parallel_group(Range&& range,-    constraint_t<-      is_async_operation_range<decay_t<Range>>::value-    > = 0)+    typename constraint<+      is_async_operation_range<typename std::decay<Range>::type>::value+    >::type = 0) {-  return ranged_parallel_group<decay_t<Range>>(std::forward<Range>(range));+  return ranged_parallel_group<typename std::decay<Range>::type>(+      std::forward<Range>(range)); }  /// Create a group of operations that may be launched in parallel.@@ -405,13 +394,29 @@  *  * For example:  * @code- * using op_type =- *   decltype(socket1.async_read_some(asio::buffer(data1)));+ * using op_type = decltype(+ *     socket1.async_read_some(+ *       asio::buffer(data1),+ *       asio::deferred+ *     )+ *   );  *  * std::vector<op_type> ops;- * ops.push_back(socket1.async_read_some(asio::buffer(data1)));- * ops.push_back(socket2.async_read_some(asio::buffer(data2)));  *+ * ops.push_back(+ *     socket1.async_read_some(+ *       asio::buffer(data1),+ *       asio::deferred+ *     )+ *   );+ *+ * ops.push_back(+ *     socket2.async_read_some(+ *       asio::buffer(data2),+ *       asio::deferred+ *     )+ *   );+ *  * asio::experimental::make_parallel_group(  *     std::allocator_arg_t,  *     my_allocator,@@ -435,13 +440,14 @@  * @endcode  */ template <typename Allocator, typename Range>-ASIO_NODISCARD inline ranged_parallel_group<decay_t<Range>, Allocator>+ASIO_NODISCARD inline+ranged_parallel_group<typename std::decay<Range>::type, Allocator> make_parallel_group(allocator_arg_t, const Allocator& allocator, Range&& range,-    constraint_t<-      is_async_operation_range<decay_t<Range>>::value-    > = 0)+    typename constraint<+      is_async_operation_range<typename std::decay<Range>::type>::value+    >::type = 0) {-  return ranged_parallel_group<decay_t<Range>, Allocator>(+  return ranged_parallel_group<typename std::decay<Range>::type, Allocator>(       std::forward<Range>(range), allocator); } 
+ link/modules/asio-standalone/asio/include/asio/experimental/prepend.hpp view
@@ -0,0 +1,36 @@+//+// experimental/prepend.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_EXPERIMENTAL_PREPEND_HPP+#define ASIO_EXPERIMENTAL_PREPEND_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/prepend.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace experimental {++#if !defined(ASIO_NO_DEPRECATED)+using asio::prepend_t;+using asio::prepend;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace experimental+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_EXPERIMENTAL_PREPEND_HPP
link/modules/asio-standalone/asio/include/asio/experimental/promise.hpp view
@@ -84,9 +84,8 @@  * awaitable<void> read_write_some(asio::ip::tcp::socket & sock,  *     asio::mutable_buffer read_buf, asio::const_buffer to_write)  * {- *   auto p = asio::async_read(read_buf,- *       asio::experimental::use_promise);- *   co_await asio::async_write_some(to_write);+ *   auto p = asio::async_read(read_buf, asio::use_awaitable);+ *   co_await asio::async_write_some(to_write, asio::deferred);  *   co_await p;  * }  * @endcode@@ -139,6 +138,7 @@    * It is safe to destruct a promise of a promise that didn't complete.    */   ~promise() { cancel(); }+  private: #if !defined(GENERATING_DOCUMENTATION)
link/modules/asio-standalone/asio/include/asio/experimental/use_coro.hpp view
@@ -47,9 +47,8 @@  * the asynchronous operation completes, and the result of the operation is  * returned.  *- * Note that this token is not the most efficient (use the default completion- * token @c asio::deferred for that) but does provide type erasure, as it- * will always return a @c coro.+ * Note that this token is not the most efficient (use @c asio::deferred+ * for that) but does provide type erasure, as it will always return a @c coro.  */ template <typename Allocator = std::allocator<void>> struct use_coro_t@@ -60,7 +59,7 @@   typedef Allocator allocator_type;    /// Default constructor.-  constexpr use_coro_t(+  ASIO_CONSTEXPR use_coro_t(       allocator_type allocator = allocator_type{} #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION)@@ -84,6 +83,7 @@   {   } +   /// Specify an alternate allocator.   template <typename OtherAllocator>   use_coro_t<OtherAllocator> rebind(const OtherAllocator& allocator) const@@ -98,7 +98,7 @@   }    /// Constructor used to specify file name, line, and function name.-  constexpr use_coro_t(const char* file_name,+  ASIO_CONSTEXPR use_coro_t(const char* file_name,       int line, const char* function_name,       allocator_type allocator = allocator_type{}) : #if defined(ASIO_ENABLE_HANDLER_TRACKING)@@ -126,13 +126,13 @@     /// Construct the adapted executor from the inner executor type.     template <typename InnerExecutor1>     executor_with_default(const InnerExecutor1& ex,-        constraint_t<-          conditional_t<+        typename constraint<+          conditional<             !is_same<InnerExecutor1, executor_with_default>::value,             is_convertible<InnerExecutor1, InnerExecutor>,             false_type-          >::value-        > = 0) noexcept+          >::type::value+        >::type = 0) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -140,21 +140,25 @@    /// Type alias to adapt an I/O object to use @c use_coro_t as its   /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)   template <typename T>   using as_default_on_t = typename T::template rebind_executor<-      executor_with_default<typename T::executor_type>>::other;+      executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)    /// Function helper to adapt an I/O object to use @c use_coro_t as its   /// default completion token type.   template <typename T>-  static typename decay_t<T>::template rebind_executor<-      executor_with_default<typename decay_t<T>::executor_type>+  static typename decay<T>::type::template rebind_executor<+      executor_with_default<typename decay<T>::type::executor_type>     >::other-  as_default_on(T&& object)+  as_default_on(ASIO_MOVE_ARG(T) object)   {-    return typename decay_t<T>::template rebind_executor<-        executor_with_default<typename decay_t<T>::executor_type>-      >::other(static_cast<T&&>(object));+    return typename decay<T>::type::template rebind_executor<+        executor_with_default<typename decay<T>::type::executor_type>+      >::other(ASIO_MOVE_CAST(T)(object));   }  #if defined(ASIO_ENABLE_HANDLER_TRACKING)@@ -173,9 +177,11 @@  * See the documentation for asio::use_coro_t for a usage example.  */ #if defined(GENERATING_DOCUMENTATION)-ASIO_INLINE_VARIABLE constexpr use_coro_t<> use_coro;-#else-ASIO_INLINE_VARIABLE constexpr use_coro_t<> use_coro(0, 0, 0);+constexpr use_coro_t<> use_coro;+#elif defined(ASIO_HAS_CONSTEXPR)+constexpr use_coro_t<> use_coro(0, 0, 0);+#elif defined(ASIO_MSVC)+__declspec(selectany) use_coro_t<> use_coro(0, 0, 0); #endif  } // namespace experimental
link/modules/asio-standalone/asio/include/asio/experimental/use_promise.hpp view
@@ -33,7 +33,7 @@   typedef Allocator allocator_type;    /// Construct using default-constructed allocator.-  constexpr use_promise_t()+  ASIO_CONSTEXPR use_promise_t()   {   } @@ -44,7 +44,7 @@   }    /// Obtain allocator.-  allocator_type get_allocator() const noexcept+  allocator_type get_allocator() const ASIO_NOEXCEPT   {     return allocator_;   }@@ -58,7 +58,7 @@     typedef use_promise_t<Allocator> default_completion_token_type;      /// Construct the adapted executor from the inner executor type.-    executor_with_default(const InnerExecutor& ex) noexcept+    executor_with_default(const InnerExecutor& ex) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -67,9 +67,9 @@     /// that to construct the adapted executor.     template <typename OtherExecutor>     executor_with_default(const OtherExecutor& ex,-        constraint_t<+        typename constraint<           is_convertible<OtherExecutor, InnerExecutor>::value-        > = 0) noexcept+        >::type = 0) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -78,14 +78,14 @@   /// Function helper to adapt an I/O object to use @c use_promise_t as its   /// default completion token type.   template <typename T>-  static typename decay_t<T>::template rebind_executor<-      executor_with_default<typename decay_t<T>::executor_type>+  static typename decay<T>::type::template rebind_executor<+      executor_with_default<typename decay<T>::type::executor_type>     >::other-  as_default_on(T&& object)+  as_default_on(ASIO_MOVE_ARG(T) object)   {-    return typename decay_t<T>::template rebind_executor<-        executor_with_default<typename decay_t<T>::executor_type>-      >::other(static_cast<T&&>(object));+    return typename decay<T>::type::template rebind_executor<+        executor_with_default<typename decay<T>::type::executor_type>+      >::other(ASIO_MOVE_CAST(T)(object));   }    /// Specify an alternate allocator.@@ -99,7 +99,7 @@   Allocator allocator_; }; -ASIO_INLINE_VARIABLE constexpr use_promise_t<> use_promise;+constexpr use_promise_t<> use_promise;  } // namespace experimental } // namespace asio
link/modules/asio-standalone/asio/include/asio/file_base.hpp view
@@ -2,7 +2,7 @@ // file_base.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/generic/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // generic/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -54,7 +54,7 @@ #endif    /// Default constructor.-  basic_endpoint() noexcept+  basic_endpoint() ASIO_NOEXCEPT   {   } @@ -78,11 +78,13 @@   {   } +#if defined(ASIO_HAS_MOVE)   /// Move constructor.   basic_endpoint(basic_endpoint&& other)     : impl_(other.impl_)   {   }+#endif // defined(ASIO_HAS_MOVE)    /// Assign from another endpoint.   basic_endpoint& operator=(const basic_endpoint& other)@@ -91,12 +93,14 @@     return *this;   } +#if defined(ASIO_HAS_MOVE)   /// Move-assign from another endpoint.   basic_endpoint& operator=(basic_endpoint&& other)   {     impl_ = other.impl_;     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    /// The protocol associated with the endpoint.   protocol_type protocol() const
link/modules/asio-standalone/asio/include/asio/generic/datagram_protocol.hpp view
@@ -2,7 +2,7 @@ // generic/datagram_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -73,19 +73,19 @@   }    /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return ASIO_OS_DEF(SOCK_DGRAM);   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return protocol_;   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return family_;   }
link/modules/asio-standalone/asio/include/asio/generic/detail/endpoint.hpp view
@@ -2,7 +2,7 @@ // generic/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/generic/detail/impl/endpoint.ipp view
@@ -2,7 +2,7 @@ // generic/detail/impl/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/generic/raw_protocol.hpp view
@@ -2,7 +2,7 @@ // generic/raw_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -73,19 +73,19 @@   }    /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return ASIO_OS_DEF(SOCK_RAW);   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return protocol_;   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return family_;   }
link/modules/asio-standalone/asio/include/asio/generic/seq_packet_protocol.hpp view
@@ -2,7 +2,7 @@ // generic/seq_packet_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -72,19 +72,19 @@   }    /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return ASIO_OS_DEF(SOCK_SEQPACKET);   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return protocol_;   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return family_;   }
link/modules/asio-standalone/asio/include/asio/generic/stream_protocol.hpp view
@@ -2,7 +2,7 @@ // generic/stream_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -74,19 +74,19 @@   }    /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return ASIO_OS_DEF(SOCK_STREAM);   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return protocol_;   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return family_;   }
+ link/modules/asio-standalone/asio/include/asio/handler_alloc_hook.hpp view
@@ -0,0 +1,104 @@+//+// handler_alloc_hook.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_HANDLER_ALLOC_HOOK_HPP+#define ASIO_HANDLER_ALLOC_HOOK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include <cstddef>++#include "asio/detail/push_options.hpp"++namespace asio {++#if defined(ASIO_NO_DEPRECATED)++// Places in asio that would have previously called the allocate or deallocate+// hooks to manage memory, now call them only to check whether the result types+// are these types. If the result is not the correct type, it indicates that+// the user code still has the old hooks in place, and if so we want to trigger+// a compile error.+enum asio_handler_allocate_is_no_longer_used {};+enum asio_handler_deallocate_is_no_longer_used {};++typedef asio_handler_allocate_is_no_longer_used+  asio_handler_allocate_is_deprecated;+typedef asio_handler_deallocate_is_no_longer_used+  asio_handler_deallocate_is_deprecated;++#else // defined(ASIO_NO_DEPRECATED)++typedef void* asio_handler_allocate_is_deprecated;+typedef void asio_handler_deallocate_is_deprecated;++#endif // defined(ASIO_NO_DEPRECATED)++/// (Deprecated: Use the associated_allocator trait.) Default allocation+/// function for handlers.+/**+ * Asynchronous operations may need to allocate temporary objects. Since+ * asynchronous operations have a handler function object, these temporary+ * objects can be said to be associated with the handler.+ *+ * Implement asio_handler_allocate and asio_handler_deallocate for your own+ * handlers to provide custom allocation for these temporary objects.+ *+ * The default implementation of these allocation hooks uses <tt>::operator+ * new</tt> and <tt>::operator delete</tt>.+ *+ * @note All temporary objects associated with a handler will be deallocated+ * before the upcall to the handler is performed. This allows the same memory to+ * be reused for a subsequent asynchronous operation initiated by the handler.+ *+ * @par Example+ * @code+ * class my_handler;+ *+ * void* asio_handler_allocate(std::size_t size, my_handler* context)+ * {+ *   return ::operator new(size);+ * }+ *+ * void asio_handler_deallocate(void* pointer, std::size_t size,+ *     my_handler* context)+ * {+ *   ::operator delete(pointer);+ * }+ * @endcode+ */+ASIO_DECL asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size, ...);++/// Default deallocation function for handlers.+/**+ * Implement asio_handler_allocate and asio_handler_deallocate for your own+ * handlers to provide custom allocation for the associated temporary objects.+ *+ * The default implementation of these allocation hooks uses <tt>::operator+ * new</tt> and <tt>::operator delete</tt>.+ *+ * @sa asio_handler_allocate.+ */+ASIO_DECL asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size, ...);++} // namespace asio++#include "asio/detail/pop_options.hpp"++#if defined(ASIO_HEADER_ONLY)+# include "asio/impl/handler_alloc_hook.ipp"+#endif // defined(ASIO_HEADER_ONLY)++#endif // ASIO_HANDLER_ALLOC_HOOK_HPP
link/modules/asio-standalone/asio/include/asio/handler_continuation_hook.hpp view
@@ -2,7 +2,7 @@ // handler_continuation_hook.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
+ link/modules/asio-standalone/asio/include/asio/handler_invoke_hook.hpp view
@@ -0,0 +1,111 @@+//+// handler_invoke_hook.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_HANDLER_INVOKE_HOOK_HPP+#define ASIO_HANDLER_INVOKE_HOOK_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++/** @defgroup asio_handler_invoke asio::asio_handler_invoke+ *+ * @brief (Deprecated: Use the associated_executor trait.) Default invoke+ * function for handlers.+ *+ * Completion handlers for asynchronous operations are invoked by the+ * io_context associated with the corresponding object (e.g. a socket or+ * deadline_timer). Certain guarantees are made on when the handler may be+ * invoked, in particular that a handler can only be invoked from a thread that+ * is currently calling @c run() on the corresponding io_context object.+ * Handlers may subsequently be invoked through other objects (such as+ * io_context::strand objects) that provide additional guarantees.+ *+ * When asynchronous operations are composed from other asynchronous+ * operations, all intermediate handlers should be invoked using the same+ * method as the final handler. This is required to ensure that user-defined+ * objects are not accessed in a way that may violate the guarantees. This+ * hooking function ensures that the invoked method used for the final handler+ * is accessible at each intermediate step.+ *+ * Implement asio_handler_invoke for your own handlers to specify a custom+ * invocation strategy.+ *+ * This default implementation invokes the function object like so:+ * @code function(); @endcode+ * If necessary, the default implementation makes a copy of the function object+ * so that the non-const operator() can be used.+ *+ * @par Example+ * @code+ * class my_handler;+ *+ * template <typename Function>+ * void asio_handler_invoke(Function function, my_handler* context)+ * {+ *   context->strand_.dispatch(function);+ * }+ * @endcode+ */+/*@{*/++#if defined(ASIO_NO_DEPRECATED)++// Places in asio that would have previously called the invocation hook to+// execute a handler, now call it only to check whether the result type is this+// type. If the result is not this type, it indicates that the user code still+// has the old hooks in place, and if so we want to trigger a compile error.+enum asio_handler_invoke_is_no_longer_used {};++typedef asio_handler_invoke_is_no_longer_used+  asio_handler_invoke_is_deprecated;++#else // defined(ASIO_NO_DEPRECATED)++typedef void asio_handler_invoke_is_deprecated;++#endif // defined(ASIO_NO_DEPRECATED)++/// Default handler invocation hook used for non-const function objects.+template <typename Function>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function, ...)+{+  function();+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++/// Default handler invocation hook used for const function objects.+template <typename Function>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function, ...)+{+  Function tmp(function);+  tmp();+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++/*@}*/++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_HANDLER_INVOKE_HOOK_HPP
link/modules/asio-standalone/asio/include/asio/high_resolution_timer.hpp view
@@ -2,7 +2,7 @@ // high_resolution_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)+ #include "asio/basic_waitable_timer.hpp" #include "asio/detail/chrono.hpp" @@ -35,5 +38,7 @@   high_resolution_timer;  } // namespace asio++#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_HIGH_RESOLUTION_TIMER_HPP
− link/modules/asio-standalone/asio/include/asio/immediate.hpp
@@ -1,142 +0,0 @@-//-// immediate.hpp-// ~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_IMMEDIATE_HPP-#define ASIO_IMMEDIATE_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_immediate_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/dispatch.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Executor>-class initiate_immediate-{-public:-  typedef Executor executor_type;--  explicit initiate_immediate(const Executor& ex)-    : ex_(ex)-  {-  }--  executor_type get_executor() const noexcept-  {-    return ex_;-  }--  template <typename CompletionHandler>-  void operator()(CompletionHandler&& handler) const-  {-    typename associated_immediate_executor<-      CompletionHandler, executor_type>::type ex =-        (get_associated_immediate_executor)(handler, ex_);-    (dispatch)(ex, static_cast<CompletionHandler&&>(handler));-  }--private:-  Executor ex_;-};--} // namespace detail--/// Launch a trivial asynchronous operation that completes immediately.-/**- * The async_immediate function is intended for use by composed operations,- * which can delegate to this operation in order to implement the correct- * semantics for immediate completion.- *- * @param ex The asynchronous operation's I/O executor.- *- * @param token The completion token.- *- * The completion handler is immediately submitted for execution by calling- * asio::dispatch() on the handler's associated immediate executor.- *- * If the completion handler does not have a customised associated immediate- * executor, then the handler is submitted as if by calling asio::post()- * on the supplied I/O executor.- *- * @par Completion Signature- * @code void() @endcode- */-template <typename Executor,-    ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken-      = default_completion_token_t<Executor>>-inline auto async_immediate(const Executor& ex,-    NullaryToken&& token = default_completion_token_t<Executor>(),-    constraint_t<-      (execution::is_executor<Executor>::value-          && can_require<Executor, execution::blocking_t::never_t>::value)-        || is_executor<Executor>::value-    > = 0)-  -> decltype(-    async_initiate<NullaryToken, void()>(-      declval<detail::initiate_immediate<Executor>>(), token))-{-  return async_initiate<NullaryToken, void()>(-      detail::initiate_immediate<Executor>(ex), token);-}--/// Launch a trivial asynchronous operation that completes immediately.-/**- * The async_immediate function is intended for use by composed operations,- * which can delegate to this operation in order to implement the correct- * semantics for immediate completion.- *- * @param ex The execution context used to obtain the asynchronous operation's- * I/O executor.- *- * @param token The completion token.- *- * The completion handler is immediately submitted for execution by calling- * asio::dispatch() on the handler's associated immediate executor.- *- * If the completion handler does not have a customised associated immediate- * executor, then the handler is submitted as if by calling asio::post()- * on the I/O executor obtained from the supplied execution context.- *- * @par Completion Signature- * @code void() @endcode- */-template <typename ExecutionContext,-    ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken-      = default_completion_token_t<typename ExecutionContext::executor_type>>-inline auto async_immediate(ExecutionContext& ctx,-    NullaryToken&& token = default_completion_token_t<-      typename ExecutionContext::executor_type>(),-    constraint_t<-      is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)-  -> decltype(-    async_initiate<NullaryToken, void()>(-      declval<detail::initiate_immediate<-        typename ExecutionContext::executor_type>>(), token))-{-  return async_initiate<NullaryToken, void()>(-      detail::initiate_immediate<-        typename ExecutionContext::executor_type>(-          ctx.get_executor()), token);-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMMEDIATE_HPP
link/modules/asio-standalone/asio/include/asio/impl/any_completion_executor.ipp view
@@ -2,7 +2,7 @@ // impl/any_completion_executor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -25,53 +25,57 @@  namespace asio { -any_completion_executor::any_completion_executor() noexcept+any_completion_executor::any_completion_executor() ASIO_NOEXCEPT   : base_type() { } -any_completion_executor::any_completion_executor(nullptr_t) noexcept+any_completion_executor::any_completion_executor(nullptr_t) ASIO_NOEXCEPT   : base_type(nullptr_t()) { }  any_completion_executor::any_completion_executor(-    const any_completion_executor& e) noexcept+    const any_completion_executor& e) ASIO_NOEXCEPT   : base_type(static_cast<const base_type&>(e)) { }  any_completion_executor::any_completion_executor(std::nothrow_t,-    const any_completion_executor& e) noexcept+    const any_completion_executor& e) ASIO_NOEXCEPT   : base_type(static_cast<const base_type&>(e)) { } +#if defined(ASIO_HAS_MOVE) any_completion_executor::any_completion_executor(-    any_completion_executor&& e) noexcept+    any_completion_executor&& e) ASIO_NOEXCEPT   : base_type(static_cast<base_type&&>(e)) { }  any_completion_executor::any_completion_executor(std::nothrow_t,-    any_completion_executor&& e) noexcept+    any_completion_executor&& e) ASIO_NOEXCEPT   : base_type(static_cast<base_type&&>(e)) { }+#endif // defined(ASIO_HAS_MOVE)  any_completion_executor& any_completion_executor::operator=(-    const any_completion_executor& e) noexcept+    const any_completion_executor& e) ASIO_NOEXCEPT {   base_type::operator=(static_cast<const base_type&>(e));   return *this; } +#if defined(ASIO_HAS_MOVE) any_completion_executor& any_completion_executor::operator=(-    any_completion_executor&& e) noexcept+    any_completion_executor&& e) ASIO_NOEXCEPT {   base_type::operator=(static_cast<base_type&&>(e));   return *this; }+#endif // defined(ASIO_HAS_MOVE)  any_completion_executor& any_completion_executor::operator=(nullptr_t) {@@ -84,7 +88,7 @@ }  void any_completion_executor::swap(-    any_completion_executor& other) noexcept+    any_completion_executor& other) ASIO_NOEXCEPT {   static_cast<base_type&>(*this).swap(static_cast<base_type&>(other)); }
link/modules/asio-standalone/asio/include/asio/impl/any_io_executor.ipp view
@@ -2,7 +2,7 @@ // impl/any_io_executor.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -25,48 +25,55 @@  namespace asio { -any_io_executor::any_io_executor() noexcept+any_io_executor::any_io_executor() ASIO_NOEXCEPT   : base_type() { } -any_io_executor::any_io_executor(nullptr_t) noexcept+any_io_executor::any_io_executor(nullptr_t) ASIO_NOEXCEPT   : base_type(nullptr_t()) { } -any_io_executor::any_io_executor(const any_io_executor& e) noexcept+any_io_executor::any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT   : base_type(static_cast<const base_type&>(e)) { }  any_io_executor::any_io_executor(std::nothrow_t,-    const any_io_executor& e) noexcept+    const any_io_executor& e) ASIO_NOEXCEPT   : base_type(static_cast<const base_type&>(e)) { } -any_io_executor::any_io_executor(any_io_executor&& e) noexcept+#if defined(ASIO_HAS_MOVE)+any_io_executor::any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT   : base_type(static_cast<base_type&&>(e)) { } -any_io_executor::any_io_executor(std::nothrow_t, any_io_executor&& e) noexcept+any_io_executor::any_io_executor(std::nothrow_t,+    any_io_executor&& e) ASIO_NOEXCEPT   : base_type(static_cast<base_type&&>(e)) { }+#endif // defined(ASIO_HAS_MOVE) -any_io_executor& any_io_executor::operator=(const any_io_executor& e) noexcept+any_io_executor& any_io_executor::operator=(+    const any_io_executor& e) ASIO_NOEXCEPT {   base_type::operator=(static_cast<const base_type&>(e));   return *this; } -any_io_executor& any_io_executor::operator=(any_io_executor&& e) noexcept+#if defined(ASIO_HAS_MOVE)+any_io_executor& any_io_executor::operator=(+    any_io_executor&& e) ASIO_NOEXCEPT {   base_type::operator=(static_cast<base_type&&>(e));   return *this; }+#endif // defined(ASIO_HAS_MOVE)  any_io_executor& any_io_executor::operator=(nullptr_t) {@@ -78,7 +85,7 @@ { } -void any_io_executor::swap(any_io_executor& other) noexcept+void any_io_executor::swap(any_io_executor& other) ASIO_NOEXCEPT {   static_cast<base_type&>(*this).swap(static_cast<base_type&>(other)); }
link/modules/asio-standalone/asio/include/asio/impl/append.hpp view
@@ -2,7 +2,7 @@ // impl/append.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,12 +16,15 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp" @@ -36,26 +39,26 @@   typedef void result_type;    template <typename H>-  append_handler(H&& handler, std::tuple<Values...> values)-    : handler_(static_cast<H&&>(handler)),-      values_(static_cast<std::tuple<Values...>&&>(values))+  append_handler(ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)+    : handler_(ASIO_MOVE_CAST(H)(handler)),+      values_(ASIO_MOVE_CAST(std::tuple<Values...>)(values))   {   }    template <typename... Args>-  void operator()(Args&&... args)+  void operator()(ASIO_MOVE_ARG(Args)... args)   {     this->invoke(         index_sequence_for<Values...>{},-        static_cast<Args&&>(args)...);+        ASIO_MOVE_CAST(Args)(args)...);   }    template <std::size_t... I, typename... Args>-  void invoke(index_sequence<I...>, Args&&... args)+  void invoke(index_sequence<I...>, ASIO_MOVE_ARG(Args)... args)   {-    static_cast<Handler&&>(handler_)(-        static_cast<Args&&>(args)...,-        static_cast<Values&&>(std::get<I>(values_))...);+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        ASIO_MOVE_CAST(Args)(args)...,+        ASIO_MOVE_CAST(Values)(std::get<I>(values_))...);   }  //private:@@ -64,6 +67,32 @@ };  template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    append_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    append_handler<Handler>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation(     append_handler<Handler>* this_handler) {@@ -71,13 +100,37 @@       this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    append_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    append_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature, typename... Values> struct append_signature;  template <typename R, typename... Args, typename... Values> struct append_signature<R(Args...), Values...> {-  typedef R type(decay_t<Args>..., Values...);+  typedef R type(typename decay<Args>::type..., Values...); };  } // namespace detail@@ -85,7 +138,8 @@ #if !defined(GENERATING_DOCUMENTATION)  template <typename CompletionToken, typename... Values, typename Signature>-struct async_result<append_t<CompletionToken, Values...>, Signature>+struct async_result<+    append_t<CompletionToken, Values...>, Signature>   : async_result<CompletionToken,       typename detail::append_signature<         Signature, Values...>::type>@@ -94,49 +148,48 @@       Signature, Values...>::type signature;    template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;--    template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        std::tuple<Values...> values, Args&&... args) &&+    init_wrapper(Initiation init)+      : initiation_(ASIO_MOVE_CAST(Initiation)(init))     {-      static_cast<Initiation&&>(*this)(-          detail::append_handler<decay_t<Handler>, Values...>(-            static_cast<Handler&&>(handler),-            static_cast<std::tuple<Values...>&&>(values)),-          static_cast<Args&&>(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        std::tuple<Values...> values, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        std::tuple<Values...> values,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<const Initiation&>(*this)(-          detail::append_handler<decay_t<Handler>, Values...>(-            static_cast<Handler&&>(handler),-            static_cast<std::tuple<Values...>&&>(values)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          detail::append_handler<+            typename decay<Handler>::type, Values...>(+              ASIO_MOVE_CAST(Handler)(handler),+              ASIO_MOVE_CAST(std::tuple<Values...>)(values)),+          ASIO_MOVE_CAST(Args)(args)...);     }++    Initiation initiation_;   };    template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<CompletionToken, signature>(-        declval<init_wrapper<decay_t<Initiation>>>(),-        token.token_,-        static_cast<std::tuple<Values...>&&>(token.values_),-        static_cast<Args&&>(args)...))+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature,+      (async_initiate<CompletionToken, signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<CompletionToken&>(),+        declval<std::tuple<Values...> >(),+        declval<ASIO_MOVE_ARG(Args)>()...)))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)   {     return async_initiate<CompletionToken, signature>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),+        init_wrapper<typename decay<Initiation>::type>(+          ASIO_MOVE_CAST(Initiation)(initiation)),         token.token_,-        static_cast<std::tuple<Values...>&&>(token.values_),-        static_cast<Args&&>(args)...);+        ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),+        ASIO_MOVE_CAST(Args)(args)...);   } }; @@ -146,15 +199,18 @@     detail::append_handler<Handler, Values...>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::append_handler<Handler, Values...>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::append_handler<Handler, Values...>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::append_handler<Handler, Values...>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::append_handler<Handler, Values...>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }
link/modules/asio-standalone/asio/include/asio/impl/as_tuple.hpp view
@@ -2,7 +2,7 @@ // impl/as_tuple.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,13 +16,16 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+ #include <tuple>-#include "asio/associated_executor.hpp"+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp" @@ -38,21 +41,21 @@    template <typename CompletionToken>   as_tuple_handler(as_tuple_t<CompletionToken> e)-    : handler_(static_cast<CompletionToken&&>(e.token_))+    : handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_))   {   }    template <typename RedirectedHandler>-  as_tuple_handler(RedirectedHandler&& h)-    : handler_(static_cast<RedirectedHandler&&>(h))+  as_tuple_handler(ASIO_MOVE_ARG(RedirectedHandler) h)+    : handler_(ASIO_MOVE_CAST(RedirectedHandler)(h))   {   }    template <typename... Args>-  void operator()(Args&&... args)+  void operator()(ASIO_MOVE_ARG(Args)... args)   {-    static_cast<Handler&&>(handler_)(-        std::make_tuple(static_cast<Args&&>(args)...));+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        std::make_tuple(ASIO_MOVE_CAST(Args)(args)...));   }  //private:@@ -60,6 +63,32 @@ };  template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    as_tuple_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    as_tuple_handler<Handler>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation(     as_tuple_handler<Handler>* this_handler) {@@ -67,48 +96,75 @@         this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    as_tuple_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    as_tuple_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature> struct as_tuple_signature;  template <typename R, typename... Args> struct as_tuple_signature<R(Args...)> {-  typedef R type(std::tuple<decay_t<Args>...>);+  typedef R type(std::tuple<typename decay<Args>::type...>); }; +#if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+ template <typename R, typename... Args> struct as_tuple_signature<R(Args...) &> {-  typedef R type(std::tuple<decay_t<Args>...>) &;+  typedef R type(std::tuple<typename decay<Args>::type...>) &; };  template <typename R, typename... Args> struct as_tuple_signature<R(Args...) &&> {-  typedef R type(std::tuple<decay_t<Args>...>) &&;+  typedef R type(std::tuple<typename decay<Args>::type...>) &&; }; -#if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)  template <typename R, typename... Args> struct as_tuple_signature<R(Args...) noexcept> {-  typedef R type(std::tuple<decay_t<Args>...>) noexcept;+  typedef R type(std::tuple<typename decay<Args>::type...>) noexcept; };  template <typename R, typename... Args> struct as_tuple_signature<R(Args...) & noexcept> {-  typedef R type(std::tuple<decay_t<Args>...>) & noexcept;+  typedef R type(std::tuple<typename decay<Args>::type...>) & noexcept; };  template <typename R, typename... Args> struct as_tuple_signature<R(Args...) && noexcept> {-  typedef R type(std::tuple<decay_t<Args>...>) && noexcept;+  typedef R type(std::tuple<typename decay<Args>::type...>) && noexcept; }; -#endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)  } // namespace detail @@ -120,50 +176,53 @@       typename detail::as_tuple_signature<Signatures>::type...> {   template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;--    template <typename Handler, typename... Args>-    void operator()(Handler&& handler, Args&&... args) &&+    init_wrapper(Initiation init)+      : initiation_(ASIO_MOVE_CAST(Initiation)(init))     {-      static_cast<Initiation&&>(*this)(-          detail::as_tuple_handler<decay_t<Handler>>(-            static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<const Initiation&>(*this)(-          detail::as_tuple_handler<decay_t<Handler>>(-            static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          detail::as_tuple_handler<+            typename decay<Handler>::type>(+              ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }++    Initiation initiation_;   };    template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(+  static ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+      typename detail::as_tuple_signature<Signatures>::type...)+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value,-            const CompletionToken, CompletionToken>,+        typename conditional<+          is_const<typename remove_reference<RawCompletionToken>::type>::value,+            const CompletionToken, CompletionToken>::type,         typename detail::as_tuple_signature<Signatures>::type...>(-          init_wrapper<decay_t<Initiation>>(-            static_cast<Initiation&&>(initiation)),-          token.token_, static_cast<Args&&>(args)...))+          init_wrapper<typename decay<Initiation>::type>(+            ASIO_MOVE_CAST(Initiation)(initiation)),+          token.token_, ASIO_MOVE_CAST(Args)(args)...)))   {     return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value,-          const CompletionToken, CompletionToken>,+      typename conditional<+        is_const<typename remove_reference<RawCompletionToken>::type>::value,+          const CompletionToken, CompletionToken>::type,       typename detail::as_tuple_signature<Signatures>::type...>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.token_, static_cast<Args&&>(args)...);+        init_wrapper<typename decay<Initiation>::type>(+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.token_, ASIO_MOVE_CAST(Args)(args)...);   } }; @@ -177,50 +236,53 @@       typename detail::as_tuple_signature<Signature>::type> {   template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;--    template <typename Handler, typename... Args>-    void operator()(Handler&& handler, Args&&... args) &&+    init_wrapper(Initiation init)+      : initiation_(ASIO_MOVE_CAST(Initiation)(init))     {-      static_cast<Initiation&&>(*this)(-          detail::as_tuple_handler<decay_t<Handler>>(-            static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<const Initiation&>(*this)(-          detail::as_tuple_handler<decay_t<Handler>>(-            static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          detail::as_tuple_handler<+            typename decay<Handler>::type>(+              ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     }++    Initiation initiation_;   };    template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(+  static ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+      typename detail::as_tuple_signature<Signatures>::type...)+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value,-            const CompletionToken, CompletionToken>,+        typename conditional<+          is_const<typename remove_reference<RawCompletionToken>::type>::value,+            const CompletionToken, CompletionToken>::type,         typename detail::as_tuple_signature<Signature>::type>(-          init_wrapper<decay_t<Initiation>>(-            static_cast<Initiation&&>(initiation)),-          token.token_, static_cast<Args&&>(args)...))+          init_wrapper<typename decay<Initiation>::type>(+            ASIO_MOVE_CAST(Initiation)(initiation)),+          token.token_, ASIO_MOVE_CAST(Args)(args)...)))   {     return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value,-          const CompletionToken, CompletionToken>,+      typename conditional<+        is_const<typename remove_reference<RawCompletionToken>::type>::value,+          const CompletionToken, CompletionToken>::type,       typename detail::as_tuple_signature<Signature>::type>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.token_, static_cast<Args&&>(args)...);+        init_wrapper<typename decay<Initiation>::type>(+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.token_, ASIO_MOVE_CAST(Args)(args)...);   } }; @@ -232,38 +294,20 @@     detail::as_tuple_handler<Handler>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::as_tuple_handler<Handler>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::as_tuple_handler<Handler>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::as_tuple_handler<Handler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::as_tuple_handler<Handler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);-  }-};--template <typename... Signatures>-struct async_result<partial_as_tuple, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&&, Args&&... args)-    -> decltype(-      async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        as_tuple_t<-          default_completion_token_t<associated_executor_t<Initiation>>>{},-        static_cast<Args&&>(args)...))-  {-    return async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        as_tuple_t<-          default_completion_token_t<associated_executor_t<Initiation>>>{},-        static_cast<Args&&>(args)...);   } }; 
link/modules/asio-standalone/asio/include/asio/impl/awaitable.hpp view
@@ -2,7 +2,7 @@ // impl/awaitable.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,12 +21,10 @@ #include <tuple> #include "asio/cancellation_signal.hpp" #include "asio/cancellation_state.hpp"-#include "asio/detail/memory.hpp" #include "asio/detail/thread_context.hpp" #include "asio/detail/thread_info_base.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp"-#include "asio/disposition.hpp" #include "asio/error.hpp" #include "asio/post.hpp" #include "asio/system_error.hpp"@@ -43,7 +41,8 @@ namespace asio { namespace detail { -template <typename, typename, typename> class awaitable_async_op_handler;+struct awaitable_thread_has_context_switched {};+template <typename, typename> class awaitable_async_op_handler; template <typename, typename, typename> class awaitable_async_op;  // An awaitable_thread represents a thread-of-execution that is composed of one@@ -82,17 +81,8 @@ //                                                 |                 | //                                                 +-----------------+ -class awaitable_launch_context-{-public:-  ASIO_DECL void launch(void (*pump_fn)(void*), void* arg);-  ASIO_DECL bool is_launching();-};--struct awaitable_thread_is_launching {};- template <typename Executor>-class awaitable_frame_base : public awaitable_launch_context+class awaitable_frame_base { public: #if !defined(ASIO_DISABLE_AWAITABLE_FRAME_RECYCLING)@@ -145,15 +135,19 @@     return result{this};   } -  template <typename Disposition>-  void set_disposition(Disposition&& d) noexcept+  void set_except(std::exception_ptr e) noexcept   {-    pending_exception_ = (to_exception_ptr)(static_cast<Disposition&&>(d));+    pending_exception_ = e;   } +  void set_error(const asio::error_code& ec)+  {+    this->set_except(std::make_exception_ptr(asio::system_error(ec)));+  }+   void unhandled_exception()   {-    set_disposition(std::current_exception());+    set_except(std::current_exception());   }    void rethrow_exception()@@ -181,7 +175,7 @@    template <typename Op>   auto await_transform(Op&& op,-      constraint_t<is_async_operation<Op>::value> = 0+      typename constraint<is_async_operation<Op>::value>::type = 0 #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION)       , detail::source_location location = detail::source_location::current()@@ -193,8 +187,8 @@       if (!!attached_thread_->get_cancellation_state().cancelled())         throw_error(asio::error::operation_aborted, "co_await"); -    return awaitable_async_op<-      completion_signature_of_t<Op>, decay_t<Op>, Executor>{+    return awaitable_async_op<typename completion_signature_of<Op>::type,+      typename decay<Op>::type, Executor>{         std::forward<Op>(op), this #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION)@@ -303,11 +297,11 @@       auto await_resume()       {         return this_->attached_thread_->reset_cancellation_state(-            static_cast<Filter&&>(filter_));+            ASIO_MOVE_CAST(Filter)(filter_));       }     }; -    return result{this, static_cast<Filter&&>(reset.filter)};+    return result{this, ASIO_MOVE_CAST(Filter)(reset.filter)};   }    // This await transformation resets the associated cancellation state.@@ -334,14 +328,14 @@       auto await_resume()       {         return this_->attached_thread_->reset_cancellation_state(-            static_cast<InFilter&&>(in_filter_),-            static_cast<OutFilter&&>(out_filter_));+            ASIO_MOVE_CAST(InFilter)(in_filter_),+            ASIO_MOVE_CAST(OutFilter)(out_filter_));       }     };      return result{this,-        static_cast<InFilter&&>(reset.in_filter),-        static_cast<OutFilter&&>(reset.out_filter)};+        ASIO_MOVE_CAST(InFilter)(reset.in_filter),+        ASIO_MOVE_CAST(OutFilter)(reset.out_filter)};   }    // This await transformation determines whether cancellation is propagated as@@ -405,12 +399,12 @@   // race condition.   template <typename Function>   auto await_transform(Function f,-      enable_if_t<+      typename enable_if<         is_convertible<-          result_of_t<Function(awaitable_frame_base*)>,+          typename result_of<Function(awaitable_frame_base*)>::type,           awaitable_thread<Executor>*         >::value-      >* = nullptr)+      >::type* = nullptr)   {     struct result     {@@ -440,8 +434,8 @@     return result{std::move(f), this};   } -  // Determine whether the awaitable thread is launching.-  auto await_transform(detail::awaitable_thread_is_launching) noexcept+  // Access the awaitable thread's has_context_switched_ flag.+  auto await_transform(detail::awaitable_thread_has_context_switched) noexcept   {     struct result     {@@ -456,9 +450,9 @@       {       } -      bool await_resume() const noexcept+      bool& await_resume() const noexcept       {-        return this_->is_launching();+        return this_->attached_thread_->entry_point()->has_context_switched_;       }     }; @@ -472,6 +466,7 @@    awaitable_thread<Executor>* detach_thread() noexcept   {+    attached_thread_->entry_point()->has_context_switched_ = true;     return std::exchange(attached_thread_, nullptr);   } @@ -543,14 +538,14 @@   ~awaitable_frame()   {     if (has_result_)-      std::launder(static_cast<T*>(static_cast<void*>(result_)))->~T();+      static_cast<T*>(static_cast<void*>(result_))->~T();   }    awaitable<T, Executor> get_return_object() noexcept   {     this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this);     return awaitable<T, Executor>(this);-  }+  };    template <typename U>   void return_value(U&& u)@@ -569,8 +564,7 @@   {     this->caller_ = nullptr;     this->rethrow_exception();-    return std::move(*std::launder(-          static_cast<T*>(static_cast<void*>(result_))));+    return std::move(*static_cast<T*>(static_cast<void*>(result_)));   }  private:@@ -587,7 +581,7 @@   {     this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this);     return awaitable<void, Executor>(this);-  }+  };    void return_void()   {@@ -610,6 +604,7 @@   awaitable_frame()     : top_of_stack_(0),       has_executor_(false),+      has_context_switched_(false),       throw_if_cancelled_(true)   {   }@@ -624,7 +619,7 @@   {     this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this);     return awaitable<awaitable_thread_entry_point, Executor>(this);-  }+  };    void return_void()   {@@ -638,8 +633,7 @@  private:   template <typename> friend class awaitable_frame_base;-  template <typename, typename, typename>-    friend class awaitable_async_op_handler;+  template <typename, typename> friend class awaitable_async_op_handler;   template <typename, typename> friend class awaitable_handler_base;   template <typename> friend class awaitable_thread; @@ -655,6 +649,7 @@   asio::cancellation_slot parent_cancellation_slot_;   asio::cancellation_state cancellation_state_;   bool has_executor_;+  bool has_context_switched_;   bool throw_if_cancelled_; }; @@ -723,21 +718,21 @@   }    template <typename Filter>-  void reset_cancellation_state(Filter&& filter)+  void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter)   {     bottom_of_stack_.frame_->cancellation_state_ =       cancellation_state(bottom_of_stack_.frame_->parent_cancellation_slot_,-        static_cast<Filter&&>(filter));+        ASIO_MOVE_CAST(Filter)(filter));   }    template <typename InFilter, typename OutFilter>-  void reset_cancellation_state(InFilter&& in_filter,-      OutFilter&& out_filter)+  void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,+      ASIO_MOVE_ARG(OutFilter) out_filter)   {     bottom_of_stack_.frame_->cancellation_state_ =       cancellation_state(bottom_of_stack_.frame_->parent_cancellation_slot_,-        static_cast<InFilter&&>(in_filter),-        static_cast<OutFilter&&>(out_filter));+        ASIO_MOVE_CAST(InFilter)(in_filter),+        ASIO_MOVE_CAST(OutFilter)(out_filter));   }    bool throw_if_cancelled() const@@ -759,7 +754,7 @@   void launch()   {     bottom_of_stack_.frame_->top_of_stack_->attach_thread(this);-    bottom_of_stack_.frame_->launch(&awaitable_thread::do_pump, this);+    pump();   }  protected:@@ -781,15 +776,10 @@     }   } -  static void do_pump(void* self)-  {-    static_cast<awaitable_thread*>(self)->pump();-  }-   awaitable<awaitable_thread_entry_point, Executor> bottom_of_stack_; }; -template <typename Signature, typename Executor, typename = void>+template <typename Signature, typename Executor> class awaitable_async_op_handler;  template <typename R, typename Executor>@@ -817,9 +807,74 @@   } }; +template <typename R, typename Executor>+class awaitable_async_op_handler<R(asio::error_code), Executor>+  : public awaitable_thread<Executor>+{+public:+  typedef asio::error_code* result_type;++  awaitable_async_op_handler(+      awaitable_thread<Executor>* h, result_type& result)+    : awaitable_thread<Executor>(std::move(*h)),+      result_(result)+  {+  }++  void operator()(asio::error_code ec)+  {+    result_ = &ec;+    this->entry_point()->top_of_stack_->attach_thread(this);+    this->entry_point()->top_of_stack_->clear_cancellation_slot();+    this->pump();+  }++  static void resume(result_type& result)+  {+    throw_error(*result);+  }++private:+  result_type& result_;+};++template <typename R, typename Executor>+class awaitable_async_op_handler<R(std::exception_ptr), Executor>+  : public awaitable_thread<Executor>+{+public:+  typedef std::exception_ptr* result_type;++  awaitable_async_op_handler(+      awaitable_thread<Executor>* h, result_type& result)+    : awaitable_thread<Executor>(std::move(*h)),+      result_(result)+  {+  }++  void operator()(std::exception_ptr ex)+  {+    result_ = &ex;+    this->entry_point()->top_of_stack_->attach_thread(this);+    this->entry_point()->top_of_stack_->clear_cancellation_slot();+    this->pump();+  }++  static void resume(result_type& result)+  {+    if (*result)+    {+      std::exception_ptr ex = std::exchange(*result, nullptr);+      std::rethrow_exception(ex);+    }+  }++private:+  result_type& result_;+};+ template <typename R, typename T, typename Executor>-class awaitable_async_op_handler<R(T), Executor,-    enable_if_t<!is_disposition<T>::value>>+class awaitable_async_op_handler<R(T), Executor>   : public awaitable_thread<Executor> { public:@@ -834,7 +889,7 @@    void operator()(T result)   {-    result_ = detail::addressof(result);+    result_ = &result;     this->entry_point()->top_of_stack_->attach_thread(this);     this->entry_point()->top_of_stack_->clear_cancellation_slot();     this->pump();@@ -849,13 +904,16 @@   result_type& result_; }; -template <typename R, typename Disposition, typename Executor>-class awaitable_async_op_handler<R(Disposition), Executor,-    enable_if_t<is_disposition<Disposition>::value>>+template <typename R, typename T, typename Executor>+class awaitable_async_op_handler<R(asio::error_code, T), Executor>   : public awaitable_thread<Executor> { public:-  typedef Disposition* result_type;+  struct result_type+  {+    asio::error_code* ec_;+    T* value_;+  };    awaitable_async_op_handler(       awaitable_thread<Executor>* h, result_type& result)@@ -864,36 +922,33 @@   {   } -  void operator()(Disposition d)+  void operator()(asio::error_code ec, T value)   {-    result_ = detail::addressof(d);+    result_.ec_ = &ec;+    result_.value_ = &value;     this->entry_point()->top_of_stack_->attach_thread(this);     this->entry_point()->top_of_stack_->clear_cancellation_slot();     this->pump();   } -  static void resume(result_type& result)+  static T resume(result_type& result)   {-    if (*result != no_error)-    {-      Disposition d = std::exchange(*result, Disposition());-      asio::throw_exception(static_cast<Disposition&&>(d));-    }+    throw_error(*result.ec_);+    return std::move(*result.value_);   }  private:   result_type& result_; }; -template <typename R, typename Disposition, typename T, typename Executor>-class awaitable_async_op_handler<R(Disposition, T), Executor,-    enable_if_t<is_disposition<Disposition>::value>>+template <typename R, typename T, typename Executor>+class awaitable_async_op_handler<R(std::exception_ptr, T), Executor>   : public awaitable_thread<Executor> { public:   struct result_type   {-    Disposition* disposition_;+    std::exception_ptr* ex_;     T* value_;   }; @@ -904,10 +959,10 @@   {   } -  void operator()(Disposition d, T value)+  void operator()(std::exception_ptr ex, T value)   {-    result_.disposition_ = detail::addressof(d);-    result_.value_ = detail::addressof(value);+    result_.ex_ = &ex;+    result_.value_ = &value;     this->entry_point()->top_of_stack_->attach_thread(this);     this->entry_point()->top_of_stack_->clear_cancellation_slot();     this->pump();@@ -915,10 +970,10 @@    static T resume(result_type& result)   {-    if (*result.disposition_ != no_error)+    if (*result.ex_)     {-      Disposition d = std::exchange(*result.disposition_, Disposition());-      asio::throw_exception(static_cast<Disposition&&>(d));+      std::exception_ptr ex = std::exchange(*result.ex_, nullptr);+      std::rethrow_exception(ex);     }     return std::move(*result.value_);   }@@ -927,13 +982,12 @@   result_type& result_; }; -template <typename R, typename T, typename... Ts, typename Executor>-class awaitable_async_op_handler<R(T, Ts...), Executor,-    enable_if_t<!is_disposition<T>::value>>+template <typename R, typename... Ts, typename Executor>+class awaitable_async_op_handler<R(Ts...), Executor>   : public awaitable_thread<Executor> { public:-  typedef std::tuple<T, Ts...>* result_type;+  typedef std::tuple<Ts...>* result_type;    awaitable_async_op_handler(       awaitable_thread<Executor>* h, result_type& result)@@ -945,14 +999,14 @@   template <typename... Args>   void operator()(Args&&... args)   {-    std::tuple<T, Ts...> result(std::forward<Args>(args)...);-    result_ = detail::addressof(result);+    std::tuple<Ts...> result(std::forward<Args>(args)...);+    result_ = &result;     this->entry_point()->top_of_stack_->attach_thread(this);     this->entry_point()->top_of_stack_->clear_cancellation_slot();     this->pump();   } -  static std::tuple<T, Ts...> resume(result_type& result)+  static std::tuple<Ts...> resume(result_type& result)   {     return std::move(*result);   }@@ -961,15 +1015,14 @@   result_type& result_; }; -template <typename R, typename Disposition, typename... Ts, typename Executor>-class awaitable_async_op_handler<R(Disposition, Ts...), Executor,-    enable_if_t<is_disposition<Disposition>::value>>+template <typename R, typename... Ts, typename Executor>+class awaitable_async_op_handler<R(asio::error_code, Ts...), Executor>   : public awaitable_thread<Executor> { public:   struct result_type   {-    Disposition* disposition_;+    asio::error_code* ec_;     std::tuple<Ts...>* value_;   }; @@ -981,11 +1034,11 @@   }    template <typename... Args>-  void operator()(Disposition d, Args&&... args)+  void operator()(asio::error_code ec, Args&&... args)   {-    result_.disposition_ = detail::addressof(d);+    result_.ec_ = &ec;     std::tuple<Ts...> value(std::forward<Args>(args)...);-    result_.value_ = detail::addressof(value);+    result_.value_ = &value;     this->entry_point()->top_of_stack_->attach_thread(this);     this->entry_point()->top_of_stack_->clear_cancellation_slot();     this->pump();@@ -993,10 +1046,49 @@    static std::tuple<Ts...> resume(result_type& result)   {-    if (*result.disposition_ != no_error)+    throw_error(*result.ec_);+    return std::move(*result.value_);+  }++private:+  result_type& result_;+};++template <typename R, typename... Ts, typename Executor>+class awaitable_async_op_handler<R(std::exception_ptr, Ts...), Executor>+  : public awaitable_thread<Executor>+{+public:+  struct result_type+  {+    std::exception_ptr* ex_;+    std::tuple<Ts...>* value_;+  };++  awaitable_async_op_handler(+      awaitable_thread<Executor>* h, result_type& result)+    : awaitable_thread<Executor>(std::move(*h)),+      result_(result)+  {+  }++  template <typename... Args>+  void operator()(std::exception_ptr ex, Args&&... args)+  {+    result_.ex_ = &ex;+    std::tuple<Ts...> value(std::forward<Args>(args)...);+    result_.value_ = &value;+    this->entry_point()->top_of_stack_->attach_thread(this);+    this->entry_point()->top_of_stack_->clear_cancellation_slot();+    this->pump();+  }++  static std::tuple<Ts...> resume(result_type& result)+  {+    if (*result.ex_)     {-      Disposition d = std::exchange(*result.disposition_, Disposition());-      asio::throw_exception(static_cast<Disposition&&>(d));+      std::exception_ptr ex = std::exchange(*result.ex_, nullptr);+      std::rethrow_exception(ex);     }     return std::move(*result.value_);   }
− link/modules/asio-standalone/asio/include/asio/impl/awaitable.ipp
@@ -1,48 +0,0 @@-//-// impl/awaitable.ipp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_IMPL_AWAITABLE_IPP-#define ASIO_IMPL_AWAITABLE_IPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"--#if defined(ASIO_HAS_CO_AWAIT)--#include "asio/awaitable.hpp"-#include "asio/detail/call_stack.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--void awaitable_launch_context::launch(void (*pump_fn)(void*), void* arg)-{-  call_stack<awaitable_launch_context>::context ctx(this);-  pump_fn(arg);-}--bool awaitable_launch_context::is_launching()-{-  return !!call_stack<awaitable_launch_context>::contains(this);-}--} // namespace detail-} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // defined(ASIO_HAS_CO_AWAIT)--#endif // ASIO_IMPL_AWAITABLE_IPP
link/modules/asio-standalone/asio/include/asio/impl/buffered_read_stream.hpp view
@@ -2,7 +2,7 @@ // impl/buffered_read_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,7 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/associator.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/type_traits.hpp"@@ -64,10 +66,11 @@         std::size_t previous_size, ReadHandler& handler)       : storage_(storage),         previous_size_(previous_size),-        handler_(static_cast<ReadHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     buffered_fill_handler(const buffered_fill_handler& other)       : storage_(other.storage_),         previous_size_(other.previous_size_),@@ -78,15 +81,16 @@     buffered_fill_handler(buffered_fill_handler&& other)       : storage_(other.storage_),         previous_size_(other.previous_size_),-        handler_(static_cast<ReadHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(const asio::error_code& ec,         const std::size_t bytes_transferred)     {       storage_.resize(previous_size_ + bytes_transferred);-      static_cast<ReadHandler&&>(handler_)(ec, bytes_transferred);+      ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_transferred);     }    //private:@@ -96,6 +100,32 @@   };    template <typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      buffered_fill_handler<ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      buffered_fill_handler<ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename ReadHandler>   inline bool asio_handler_is_continuation(       buffered_fill_handler<ReadHandler>* this_handler)   {@@ -103,26 +133,50 @@           this_handler->handler_);   } +  template <typename Function, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      buffered_fill_handler<ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      buffered_fill_handler<ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename Stream>   class initiate_async_buffered_fill   {   public:-    typedef typename remove_reference_t<-      Stream>::lowest_layer_type::executor_type executor_type;+    typedef typename remove_reference<+      Stream>::type::lowest_layer_type::executor_type executor_type;      explicit initiate_async_buffered_fill(-        remove_reference_t<Stream>& next_layer)+        typename remove_reference<Stream>::type& next_layer)       : next_layer_(next_layer)     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return next_layer_.lowest_layer().get_executor();     }      template <typename ReadHandler>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         buffered_stream_storage* storage) const     {       // If you get an error on the following line it means that your handler@@ -136,12 +190,12 @@           buffer(             storage->data() + previous_size,             storage->size() - previous_size),-          buffered_fill_handler<decay_t<ReadHandler>>(+          buffered_fill_handler<typename decay<ReadHandler>::type>(             *storage, previous_size, handler2.value));     }    private:-    remove_reference_t<Stream>& next_layer_;+    typename remove_reference<Stream>::type& next_layer_;   }; } // namespace detail @@ -154,15 +208,18 @@     DefaultCandidate>   : Associator<ReadHandler, DefaultCandidate> {-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::buffered_fill_handler<ReadHandler>& h) noexcept+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::buffered_fill_handler<ReadHandler>& h) ASIO_NOEXCEPT   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::buffered_fill_handler<ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::buffered_fill_handler<ReadHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -174,12 +231,15 @@ template <     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       std::size_t)) ReadHandler>-inline auto buffered_read_stream<Stream>::async_fill(ReadHandler&& handler)-  -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+    void (asio::error_code, std::size_t))+buffered_read_stream<Stream>::async_fill(+    ASIO_MOVE_ARG(ReadHandler) handler)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadHandler,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_buffered_fill<Stream>>(),-        handler, declval<detail::buffered_stream_storage*>()))+        declval<detail::initiate_async_buffered_fill<Stream> >(),+        handler, declval<detail::buffered_stream_storage*>()))) {   return async_initiate<ReadHandler,     void (asio::error_code, std::size_t)>(@@ -229,37 +289,39 @@         const MutableBufferSequence& buffers, ReadHandler& handler)       : storage_(storage),         buffers_(buffers),-        handler_(static_cast<ReadHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))     {     } -    buffered_read_some_handler(const buffered_read_some_handler& other)-      : storage_(other.storage_),-        buffers_(other.buffers_),-        handler_(other.handler_)-    {-    }+#if defined(ASIO_HAS_MOVE)+      buffered_read_some_handler(const buffered_read_some_handler& other)+        : storage_(other.storage_),+          buffers_(other.buffers_),+          handler_(other.handler_)+      {+      } -    buffered_read_some_handler(buffered_read_some_handler&& other)-      : storage_(other.storage_),-        buffers_(other.buffers_),-        handler_(static_cast<ReadHandler&&>(other.handler_))-    {-    }+      buffered_read_some_handler(buffered_read_some_handler&& other)+        : storage_(other.storage_),+          buffers_(other.buffers_),+          handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+      {+      }+#endif // defined(ASIO_HAS_MOVE)      void operator()(const asio::error_code& ec, std::size_t)     {       if (ec || storage_.empty())       {         const std::size_t length = 0;-        static_cast<ReadHandler&&>(handler_)(ec, length);+        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, length);       }       else       {         const std::size_t bytes_copied = asio::buffer_copy(             buffers_, storage_.data(), storage_.size());         storage_.consume(bytes_copied);-        static_cast<ReadHandler&&>(handler_)(ec, bytes_copied);+        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(ec, bytes_copied);       }     } @@ -270,6 +332,34 @@   };    template <typename MutableBufferSequence, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      buffered_read_some_handler<+        MutableBufferSequence, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename MutableBufferSequence, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      buffered_read_some_handler<+        MutableBufferSequence, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename MutableBufferSequence, typename ReadHandler>   inline bool asio_handler_is_continuation(       buffered_read_some_handler<         MutableBufferSequence, ReadHandler>* this_handler)@@ -278,26 +368,54 @@           this_handler->handler_);   } +  template <typename Function, typename MutableBufferSequence,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      buffered_read_some_handler<+        MutableBufferSequence, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename MutableBufferSequence,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      buffered_read_some_handler<+        MutableBufferSequence, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename Stream>   class initiate_async_buffered_read_some   {   public:-    typedef typename remove_reference_t<-      Stream>::lowest_layer_type::executor_type executor_type;+    typedef typename remove_reference<+      Stream>::type::lowest_layer_type::executor_type executor_type;      explicit initiate_async_buffered_read_some(-        remove_reference_t<Stream>& next_layer)+        typename remove_reference<Stream>::type& next_layer)       : next_layer_(next_layer)     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return next_layer_.lowest_layer().get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         buffered_stream_storage* storage,         const MutableBufferSequence& buffers) const     {@@ -309,23 +427,23 @@       non_const_lvalue<ReadHandler> handler2(handler);       if (buffer_size(buffers) == 0 || !storage->empty())       {-        next_layer_.async_read_some(mutable_buffer(0, 0),+        next_layer_.async_read_some(ASIO_MUTABLE_BUFFER(0, 0),             buffered_read_some_handler<MutableBufferSequence,-              decay_t<ReadHandler>>(+              typename decay<ReadHandler>::type>(                 *storage, buffers, handler2.value));       }       else       {         initiate_async_buffered_fill<Stream>(this->next_layer_)(             buffered_read_some_handler<MutableBufferSequence,-              decay_t<ReadHandler>>(+              typename decay<ReadHandler>::type>(                 *storage, buffers, handler2.value),             storage);       }     }    private:-    remove_reference_t<Stream>& next_layer_;+    typename remove_reference<Stream>::type& next_layer_;   }; } // namespace detail @@ -339,18 +457,20 @@     DefaultCandidate>   : Associator<ReadHandler, DefaultCandidate> {-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::buffered_read_some_handler<-        MutableBufferSequence, ReadHandler>& h) noexcept+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::buffered_read_some_handler<+        MutableBufferSequence, ReadHandler>& h) ASIO_NOEXCEPT   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::buffered_read_some_handler<+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::buffered_read_some_handler<         MutableBufferSequence, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -362,13 +482,16 @@ template <typename MutableBufferSequence,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       std::size_t)) ReadHandler>-inline auto buffered_read_stream<Stream>::async_read_some(-    const MutableBufferSequence& buffers, ReadHandler&& handler)-  -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadHandler,+    void (asio::error_code, std::size_t))+buffered_read_stream<Stream>::async_read_some(+    const MutableBufferSequence& buffers,+    ASIO_MOVE_ARG(ReadHandler) handler)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadHandler,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_buffered_read_some<Stream>>(),-        handler, declval<detail::buffered_stream_storage*>(), buffers))+        declval<detail::initiate_async_buffered_read_some<Stream> >(),+        handler, declval<detail::buffered_stream_storage*>(), buffers))) {   return async_initiate<ReadHandler,     void (asio::error_code, std::size_t)>(
link/modules/asio-standalone/asio/include/asio/impl/buffered_write_stream.hpp view
@@ -2,7 +2,7 @@ // impl/buffered_write_stream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,7 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/associator.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp" @@ -52,10 +54,11 @@     buffered_flush_handler(detail::buffered_stream_storage& storage,         WriteHandler& handler)       : storage_(storage),-        handler_(static_cast<WriteHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(WriteHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     buffered_flush_handler(const buffered_flush_handler& other)       : storage_(other.storage_),         handler_(other.handler_)@@ -64,15 +67,16 @@      buffered_flush_handler(buffered_flush_handler&& other)       : storage_(other.storage_),-        handler_(static_cast<WriteHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(const asio::error_code& ec,         const std::size_t bytes_written)     {       storage_.consume(bytes_written);-      static_cast<WriteHandler&&>(handler_)(ec, bytes_written);+      ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_written);     }    //private:@@ -81,6 +85,32 @@   };    template <typename WriteHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      buffered_flush_handler<WriteHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename WriteHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      buffered_flush_handler<WriteHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename WriteHandler>   inline bool asio_handler_is_continuation(       buffered_flush_handler<WriteHandler>* this_handler)   {@@ -88,26 +118,50 @@           this_handler->handler_);   } +  template <typename Function, typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      buffered_flush_handler<WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      buffered_flush_handler<WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename Stream>   class initiate_async_buffered_flush   {   public:-    typedef typename remove_reference_t<-      Stream>::lowest_layer_type::executor_type executor_type;+    typedef typename remove_reference<+      Stream>::type::lowest_layer_type::executor_type executor_type;      explicit initiate_async_buffered_flush(-        remove_reference_t<Stream>& next_layer)+        typename remove_reference<Stream>::type& next_layer)       : next_layer_(next_layer)     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return next_layer_.lowest_layer().get_executor();     }      template <typename WriteHandler>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         buffered_stream_storage* storage) const     {       // If you get an error on the following line it means that your handler@@ -116,12 +170,12 @@        non_const_lvalue<WriteHandler> handler2(handler);       async_write(next_layer_, buffer(storage->data(), storage->size()),-          buffered_flush_handler<decay_t<WriteHandler>>(+          buffered_flush_handler<typename decay<WriteHandler>::type>(             *storage, handler2.value));     }    private:-    remove_reference_t<Stream>& next_layer_;+    typename remove_reference<Stream>::type& next_layer_;   }; } // namespace detail @@ -134,15 +188,18 @@     DefaultCandidate>   : Associator<WriteHandler, DefaultCandidate> {-  static typename Associator<WriteHandler, DefaultCandidate>::type get(-      const detail::buffered_flush_handler<WriteHandler>& h) noexcept+  static typename Associator<WriteHandler, DefaultCandidate>::type+  get(const detail::buffered_flush_handler<WriteHandler>& h) ASIO_NOEXCEPT   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::buffered_flush_handler<WriteHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<WriteHandler, DefaultCandidate>::type)+  get(const detail::buffered_flush_handler<WriteHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -154,12 +211,15 @@ template <     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       std::size_t)) WriteHandler>-inline auto buffered_write_stream<Stream>::async_flush(WriteHandler&& handler)-  -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+    void (asio::error_code, std::size_t))+buffered_write_stream<Stream>::async_flush(+    ASIO_MOVE_ARG(WriteHandler) handler)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteHandler,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_buffered_flush<Stream>>(),-        handler, declval<detail::buffered_stream_storage*>()))+        declval<detail::initiate_async_buffered_flush<Stream> >(),+        handler, declval<detail::buffered_stream_storage*>()))) {   return async_initiate<WriteHandler,     void (asio::error_code, std::size_t)>(@@ -209,30 +269,32 @@         const ConstBufferSequence& buffers, WriteHandler& handler)       : storage_(storage),         buffers_(buffers),-        handler_(static_cast<WriteHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(WriteHandler)(handler))     {     } -    buffered_write_some_handler(const buffered_write_some_handler& other)-      : storage_(other.storage_),-        buffers_(other.buffers_),-        handler_(other.handler_)-    {-    }+#if defined(ASIO_HAS_MOVE)+      buffered_write_some_handler(const buffered_write_some_handler& other)+        : storage_(other.storage_),+          buffers_(other.buffers_),+          handler_(other.handler_)+      {+      } -    buffered_write_some_handler(buffered_write_some_handler&& other)-      : storage_(other.storage_),-        buffers_(other.buffers_),-        handler_(static_cast<WriteHandler&&>(other.handler_))-    {-    }+      buffered_write_some_handler(buffered_write_some_handler&& other)+        : storage_(other.storage_),+          buffers_(other.buffers_),+          handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))+      {+      }+#endif // defined(ASIO_HAS_MOVE)      void operator()(const asio::error_code& ec, std::size_t)     {       if (ec)       {         const std::size_t length = 0;-        static_cast<WriteHandler&&>(handler_)(ec, length);+        ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, length);       }       else       {@@ -245,7 +307,7 @@         storage_.resize(orig_size + length);         const std::size_t bytes_copied = asio::buffer_copy(             storage_.data() + orig_size, buffers_, length);-        static_cast<WriteHandler&&>(handler_)(ec, bytes_copied);+        ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_copied);       }     } @@ -256,6 +318,34 @@   };    template <typename ConstBufferSequence, typename WriteHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      buffered_write_some_handler<+        ConstBufferSequence, WriteHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename ConstBufferSequence, typename WriteHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      buffered_write_some_handler<+        ConstBufferSequence, WriteHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename ConstBufferSequence, typename WriteHandler>   inline bool asio_handler_is_continuation(       buffered_write_some_handler<         ConstBufferSequence, WriteHandler>* this_handler)@@ -264,26 +354,54 @@           this_handler->handler_);   } +  template <typename Function, typename ConstBufferSequence,+      typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      buffered_write_some_handler<+        ConstBufferSequence, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename ConstBufferSequence,+      typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      buffered_write_some_handler<+        ConstBufferSequence, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename Stream>   class initiate_async_buffered_write_some   {   public:-    typedef typename remove_reference_t<-      Stream>::lowest_layer_type::executor_type executor_type;+    typedef typename remove_reference<+      Stream>::type::lowest_layer_type::executor_type executor_type;      explicit initiate_async_buffered_write_some(-        remove_reference_t<Stream>& next_layer)+        typename remove_reference<Stream>::type& next_layer)       : next_layer_(next_layer)     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return next_layer_.lowest_layer().get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         buffered_stream_storage* storage,         const ConstBufferSequence& buffers) const     {@@ -295,23 +413,23 @@       non_const_lvalue<WriteHandler> handler2(handler);       if (buffer_size(buffers) == 0 || storage->size() < storage->capacity())       {-        next_layer_.async_write_some(const_buffer(0, 0),+        next_layer_.async_write_some(ASIO_CONST_BUFFER(0, 0),             buffered_write_some_handler<ConstBufferSequence,-              decay_t<WriteHandler>>(+              typename decay<WriteHandler>::type>(                 *storage, buffers, handler2.value));       }       else       {         initiate_async_buffered_flush<Stream>(this->next_layer_)(             buffered_write_some_handler<ConstBufferSequence,-              decay_t<WriteHandler>>(+              typename decay<WriteHandler>::type>(                 *storage, buffers, handler2.value),             storage);       }     }    private:-    remove_reference_t<Stream>& next_layer_;+    typename remove_reference<Stream>::type& next_layer_;   }; } // namespace detail @@ -325,18 +443,20 @@     DefaultCandidate>   : Associator<WriteHandler, DefaultCandidate> {-  static typename Associator<WriteHandler, DefaultCandidate>::type get(-      const detail::buffered_write_some_handler<-        ConstBufferSequence, WriteHandler>& h) noexcept+  static typename Associator<WriteHandler, DefaultCandidate>::type+  get(const detail::buffered_write_some_handler<+        ConstBufferSequence, WriteHandler>& h) ASIO_NOEXCEPT   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::buffered_write_some_handler<+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<WriteHandler, DefaultCandidate>::type)+  get(const detail::buffered_write_some_handler<         ConstBufferSequence, WriteHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -348,13 +468,16 @@ template <typename ConstBufferSequence,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       std::size_t)) WriteHandler>-inline auto buffered_write_stream<Stream>::async_write_some(-    const ConstBufferSequence& buffers, WriteHandler&& handler)-  -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteHandler,+    void (asio::error_code, std::size_t))+buffered_write_stream<Stream>::async_write_some(+    const ConstBufferSequence& buffers,+    ASIO_MOVE_ARG(WriteHandler) handler)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteHandler,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_buffered_write_some<Stream>>(),-        handler, declval<detail::buffered_stream_storage*>(), buffers))+        declval<detail::initiate_async_buffered_write_some<Stream> >(),+        handler, declval<detail::buffered_stream_storage*>(), buffers))) {   return async_initiate<WriteHandler,     void (asio::error_code, std::size_t)>(
− link/modules/asio-standalone/asio/include/asio/impl/cancel_after.hpp
@@ -1,268 +0,0 @@-//-// impl/cancel_after.hpp-// ~~~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_IMPL_CANCEL_AFTER_HPP-#define ASIO_IMPL_CANCEL_AFTER_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/timed_cancel_op.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Initiation, typename Clock,-    typename WaitTraits, typename... Signatures>-struct initiate_cancel_after : initiation_base<Initiation>-{-  using initiation_base<Initiation>::initiation_base;--  template <typename Handler, typename Rep, typename Period, typename... Args>-  void operator()(Handler&& handler,-      const chrono::duration<Rep, Period>& timeout,-      cancellation_type_t cancel_type, Args&&... args) &&-  {-    using op = detail::timed_cancel_op<decay_t<Handler>,-        basic_waitable_timer<Clock, WaitTraits>, Signatures...>;--    non_const_lvalue<Handler> handler2(handler);-    typename op::ptr p = { asio::detail::addressof(handler2.value),-        op::ptr::allocate(handler2.value), 0 };-    p.p = new (p.v) op(handler2.value,-        basic_waitable_timer<Clock, WaitTraits,-          typename Initiation::executor_type>(this->get_executor(), timeout),-        cancel_type);--    op* o = p.p;-    p.v = p.p = 0;-    o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);-  }--  template <typename Handler, typename Rep, typename Period, typename... Args>-  void operator()(Handler&& handler,-      const chrono::duration<Rep, Period>& timeout,-      cancellation_type_t cancel_type, Args&&... args) const &-  {-    using op = detail::timed_cancel_op<decay_t<Handler>,-        basic_waitable_timer<Clock, WaitTraits>, Signatures...>;--    non_const_lvalue<Handler> handler2(handler);-    typename op::ptr p = { asio::detail::addressof(handler2.value),-        op::ptr::allocate(handler2.value), 0 };-    p.p = new (p.v) op(handler2.value,-        basic_waitable_timer<Clock, WaitTraits,-          typename Initiation::executor_type>(this->get_executor(), timeout),-        cancel_type);--    op* o = p.p;-    p.v = p.p = 0;-    o->start(static_cast<const Initiation&>(*this),-        static_cast<Args&&>(args)...);-  }-};--template <typename Initiation, typename Clock,-    typename WaitTraits, typename Executor, typename... Signatures>-struct initiate_cancel_after_timer : initiation_base<Initiation>-{-  using initiation_base<Initiation>::initiation_base;--  template <typename Handler, typename Rep, typename Period, typename... Args>-  void operator()(Handler&& handler,-      basic_waitable_timer<Clock, WaitTraits, Executor>* timer,-      const chrono::duration<Rep, Period>& timeout,-      cancellation_type_t cancel_type, Args&&... args) &&-  {-    using op = detail::timed_cancel_op<decay_t<Handler>,-        basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;--    non_const_lvalue<Handler> handler2(handler);-    typename op::ptr p = { asio::detail::addressof(handler2.value),-        op::ptr::allocate(handler2.value), 0 };-    timer->expires_after(timeout);-    p.p = new (p.v) op(handler2.value, *timer, cancel_type);--    op* o = p.p;-    p.v = p.p = 0;-    o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);-  }--  template <typename Handler, typename Rep, typename Period, typename... Args>-  void operator()(Handler&& handler,-      basic_waitable_timer<Clock, WaitTraits, Executor>* timer,-      const chrono::duration<Rep, Period>& timeout,-      cancellation_type_t cancel_type, Args&&... args) const &-  {-    using op = detail::timed_cancel_op<decay_t<Handler>,-        basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;--    non_const_lvalue<Handler> handler2(handler);-    typename op::ptr p = { asio::detail::addressof(handler2.value),-        op::ptr::allocate(handler2.value), 0 };-    timer->expires_after(timeout);-    p.p = new (p.v) op(handler2.value, *timer, cancel_type);--    op* o = p.p;-    p.v = p.p = 0;-    o->start(static_cast<const Initiation&>(*this),-        static_cast<Args&&>(args)...);-  }-};--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken, typename Clock,-    typename WaitTraits, typename... Signatures>-struct async_result<-    cancel_after_t<CompletionToken, Clock, WaitTraits>, Signatures...>-  : async_result<CompletionToken, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value,-            const CompletionToken, CompletionToken>,-        Signatures...>(-          declval<detail::initiate_cancel_after<-            decay_t<Initiation>, Clock, WaitTraits, Signatures...>>(),-          token.token_, token.timeout_, token.cancel_type_,-          static_cast<Args&&>(args)...))-  {-    return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value,-          const CompletionToken, CompletionToken>,-      Signatures...>(-        detail::initiate_cancel_after<-          decay_t<Initiation>, Clock, WaitTraits, Signatures...>(-            static_cast<Initiation&&>(initiation)),-        token.token_, token.timeout_, token.cancel_type_,-        static_cast<Args&&>(args)...);-  }-};--template <typename CompletionToken, typename Clock,-    typename WaitTraits, typename Executor, typename... Signatures>-struct async_result<-    cancel_after_timer<CompletionToken, Clock, WaitTraits, Executor>,-    Signatures...>-  : async_result<CompletionToken, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value,-            const CompletionToken, CompletionToken>,-        Signatures...>(-          declval<detail::initiate_cancel_after_timer<-            decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>>(),-          token.token_, &token.timer_, token.timeout_,-          token.cancel_type_, static_cast<Args&&>(args)...))-  {-    return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value,-          const CompletionToken, CompletionToken>,-      Signatures...>(-        detail::initiate_cancel_after_timer<-          decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>(-            static_cast<Initiation&&>(initiation)),-        token.token_, &token.timer_, token.timeout_,-        token.cancel_type_, static_cast<Args&&>(args)...);-  }-};--template <typename Clock, typename WaitTraits, typename... Signatures>-struct async_result<partial_cancel_after<Clock, WaitTraits>, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        const cancel_after_t<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Clock, WaitTraits>&,-        Signatures...>(-          static_cast<Initiation&&>(initiation),-          cancel_after_t<-            default_completion_token_t<associated_executor_t<Initiation>>,-            Clock, WaitTraits>(-              default_completion_token_t<associated_executor_t<Initiation>>{},-              token.timeout_, token.cancel_type_),-          static_cast<Args&&>(args)...))-  {-    return async_initiate<-      const cancel_after_t<-        default_completion_token_t<associated_executor_t<Initiation>>,-        Clock, WaitTraits>&,-      Signatures...>(-        static_cast<Initiation&&>(initiation),-        cancel_after_t<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Clock, WaitTraits>(-            default_completion_token_t<associated_executor_t<Initiation>>{},-            token.timeout_, token.cancel_type_),-        static_cast<Args&&>(args)...);-  }-};--template <typename Clock, typename WaitTraits,-    typename Executor, typename... Signatures>-struct async_result<-    partial_cancel_after_timer<Clock, WaitTraits, Executor>, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        cancel_after_timer<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Clock, WaitTraits, Executor>(-            default_completion_token_t<associated_executor_t<Initiation>>{},-            token.timer_, token.timeout_, token.cancel_type_),-        static_cast<Args&&>(args)...))-  {-    return async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        cancel_after_timer<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Clock, WaitTraits, Executor>(-            default_completion_token_t<associated_executor_t<Initiation>>{},-            token.timer_, token.timeout_, token.cancel_type_),-        static_cast<Args&&>(args)...);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMPL_CANCEL_AFTER_HPP
− link/modules/asio-standalone/asio/include/asio/impl/cancel_at.hpp
@@ -1,268 +0,0 @@-//-// impl/cancel_at.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_IMPL_CANCEL_AT_HPP-#define ASIO_IMPL_CANCEL_AT_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/detail/initiation_base.hpp"-#include "asio/detail/timed_cancel_op.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename Initiation, typename Clock,-    typename WaitTraits, typename... Signatures>-struct initiate_cancel_at : initiation_base<Initiation>-{-  using initiation_base<Initiation>::initiation_base;--  template <typename Handler, typename Duration, typename... Args>-  void operator()(Handler&& handler,-      const chrono::time_point<Clock, Duration>& expiry,-      cancellation_type_t cancel_type, Args&&... args) &&-  {-    using op = detail::timed_cancel_op<decay_t<Handler>,-        basic_waitable_timer<Clock, WaitTraits>, Signatures...>;--    non_const_lvalue<Handler> handler2(handler);-    typename op::ptr p = { asio::detail::addressof(handler2.value),-        op::ptr::allocate(handler2.value), 0 };-    p.p = new (p.v) op(handler2.value,-        basic_waitable_timer<Clock, WaitTraits,-          typename Initiation::executor_type>(this->get_executor(), expiry),-        cancel_type);--    op* o = p.p;-    p.v = p.p = 0;-    o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);-  }--  template <typename Handler, typename Duration, typename... Args>-  void operator()(Handler&& handler,-      const chrono::time_point<Clock, Duration>& expiry,-      cancellation_type_t cancel_type, Args&&... args) const &-  {-    using op = detail::timed_cancel_op<decay_t<Handler>,-        basic_waitable_timer<Clock, WaitTraits>, Signatures...>;--    non_const_lvalue<Handler> handler2(handler);-    typename op::ptr p = { asio::detail::addressof(handler2.value),-        op::ptr::allocate(handler2.value), 0 };-    p.p = new (p.v) op(handler2.value,-        basic_waitable_timer<Clock, WaitTraits,-          typename Initiation::executor_type>(this->get_executor(), expiry),-        cancel_type);--    op* o = p.p;-    p.v = p.p = 0;-    o->start(static_cast<const Initiation&>(*this),-        static_cast<Args&&>(args)...);-  }-};--template <typename Initiation, typename Clock,-    typename WaitTraits, typename Executor, typename... Signatures>-struct initiate_cancel_at_timer : initiation_base<Initiation>-{-  using initiation_base<Initiation>::initiation_base;--  template <typename Handler, typename Duration, typename... Args>-  void operator()(Handler&& handler,-      basic_waitable_timer<Clock, WaitTraits, Executor>* timer,-      const chrono::time_point<Clock, Duration>& expiry,-      cancellation_type_t cancel_type, Args&&... args) &&-  {-    using op = detail::timed_cancel_op<decay_t<Handler>,-        basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;--    non_const_lvalue<Handler> handler2(handler);-    typename op::ptr p = { asio::detail::addressof(handler2.value),-        op::ptr::allocate(handler2.value), 0 };-    timer->expires_at(expiry);-    p.p = new (p.v) op(handler2.value, *timer, cancel_type);--    op* o = p.p;-    p.v = p.p = 0;-    o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);-  }--  template <typename Handler, typename Duration, typename... Args>-  void operator()(Handler&& handler,-      basic_waitable_timer<Clock, WaitTraits, Executor>* timer,-      const chrono::time_point<Clock, Duration>& expiry,-      cancellation_type_t cancel_type, Args&&... args) const &-  {-    using op = detail::timed_cancel_op<decay_t<Handler>,-        basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;--    non_const_lvalue<Handler> handler2(handler);-    typename op::ptr p = { asio::detail::addressof(handler2.value),-        op::ptr::allocate(handler2.value), 0 };-    timer->expires_at(expiry);-    p.p = new (p.v) op(handler2.value, *timer, cancel_type);--    op* o = p.p;-    p.v = p.p = 0;-    o->start(static_cast<const Initiation&>(*this),-        static_cast<Args&&>(args)...);-  }-};--} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <typename CompletionToken, typename Clock,-    typename WaitTraits, typename... Signatures>-struct async_result<-    cancel_at_t<CompletionToken, Clock, WaitTraits>, Signatures...>-  : async_result<CompletionToken, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value,-            const CompletionToken, CompletionToken>,-        Signatures...>(-          declval<detail::initiate_cancel_at<-            decay_t<Initiation>, Clock, WaitTraits, Signatures...>>(),-          token.token_, token.expiry_, token.cancel_type_,-          static_cast<Args&&>(args)...))-  {-    return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value,-          const CompletionToken, CompletionToken>,-      Signatures...>(-        detail::initiate_cancel_at<-          decay_t<Initiation>, Clock, WaitTraits, Signatures...>(-            static_cast<Initiation&&>(initiation)),-        token.token_, token.expiry_, token.cancel_type_,-        static_cast<Args&&>(args)...);-  }-};--template <typename CompletionToken, typename Clock,-    typename WaitTraits, typename Executor, typename... Signatures>-struct async_result<-    cancel_at_timer<CompletionToken, Clock, WaitTraits, Executor>,-    Signatures...>-  : async_result<CompletionToken, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value,-            const CompletionToken, CompletionToken>,-        Signatures...>(-          declval<detail::initiate_cancel_at_timer<-            decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>>(),-          token.token_, &token.timer_, token.expiry_, token.cancel_type_,-          static_cast<Args&&>(args)...))-  {-    return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value,-          const CompletionToken, CompletionToken>,-      Signatures...>(-        detail::initiate_cancel_at_timer<-          decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>(-            static_cast<Initiation&&>(initiation)),-        token.token_, &token.timer_, token.expiry_, token.cancel_type_,-        static_cast<Args&&>(args)...);-  }-};--template <typename Clock, typename WaitTraits, typename... Signatures>-struct async_result<partial_cancel_at<Clock, WaitTraits>, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        const cancel_at_t<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Clock, WaitTraits>&,-        Signatures...>(-          static_cast<Initiation&&>(initiation),-          cancel_at_t<-            default_completion_token_t<associated_executor_t<Initiation>>,-            Clock, WaitTraits>(-              default_completion_token_t<associated_executor_t<Initiation>>{},-              token.expiry_, token.cancel_type_),-          static_cast<Args&&>(args)...))-  {-    return async_initiate<-      const cancel_at_t<-        default_completion_token_t<associated_executor_t<Initiation>>,-        Clock, WaitTraits>&,-      Signatures...>(-        static_cast<Initiation&&>(initiation),-        cancel_at_t<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Clock, WaitTraits>(-            default_completion_token_t<associated_executor_t<Initiation>>{},-            token.expiry_, token.cancel_type_),-        static_cast<Args&&>(args)...);-  }-};--template <typename Clock, typename WaitTraits,-    typename Executor, typename... Signatures>-struct async_result<-    partial_cancel_at_timer<Clock, WaitTraits, Executor>, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        cancel_at_timer<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Clock, WaitTraits, Executor>(-            default_completion_token_t<associated_executor_t<Initiation>>{},-            token.timer_, token.expiry_, token.cancel_type_),-        static_cast<Args&&>(args)...))-  {-    return async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        cancel_at_timer<-          default_completion_token_t<associated_executor_t<Initiation>>,-          Clock, WaitTraits, Executor>(-            default_completion_token_t<associated_executor_t<Initiation>>{},-            token.timer_, token.expiry_, token.cancel_type_),-        static_cast<Args&&>(args)...);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMPL_CANCEL_AT_HPP
link/modules/asio-standalone/asio/include/asio/impl/cancellation_signal.ipp view
@@ -2,7 +2,7 @@ // impl/cancellation_signal.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/impl/co_spawn.hpp view
@@ -2,7 +2,7 @@ // impl/co_spawn.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,8 +18,6 @@ #include "asio/detail/config.hpp" #include "asio/associated_cancellation_slot.hpp" #include "asio/awaitable.hpp"-#include "asio/detail/memory.hpp"-#include "asio/detail/recycling_allocator.hpp" #include "asio/dispatch.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/post.hpp"@@ -35,18 +33,18 @@ class co_spawn_work_guard { public:-  typedef decay_t<-      prefer_result_t<Executor,+  typedef typename decay<+      typename prefer_result<Executor,         execution::outstanding_work_t::tracked_t-      >-    > executor_type;+      >::type+    >::type executor_type;    co_spawn_work_guard(const Executor& ex)     : executor_(asio::prefer(ex, execution::outstanding_work.tracked))   {   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return executor_;   }@@ -59,9 +57,9 @@  template <typename Executor> struct co_spawn_work_guard<Executor,-    enable_if_t<+    typename enable_if<       !execution::is_executor<Executor>::value-    >> : executor_work_guard<Executor>+    >::type> : executor_work_guard<Executor> {   co_spawn_work_guard(const Executor& ex)     : executor_work_guard<Executor>(ex)@@ -71,100 +69,49 @@  #endif // !defined(ASIO_NO_TS_EXECUTORS) -template <typename Handler, typename Executor,-    typename Function, typename = void>-struct co_spawn_state-{-  template <typename H, typename F>-  co_spawn_state(H&& h, const Executor& ex, F&& f)-    : handler(std::forward<H>(h)),-      spawn_work(ex),-      handler_work(asio::get_associated_executor(handler, ex)),-      function(std::forward<F>(f))-  {-  }--  Handler handler;-  co_spawn_work_guard<Executor> spawn_work;-  co_spawn_work_guard<associated_executor_t<Handler, Executor>> handler_work;-  Function function;-};--template <typename Handler, typename Executor, typename Function>-struct co_spawn_state<Handler, Executor, Function,-    enable_if_t<-      is_same<-        typename associated_executor<Handler,-          Executor>::asio_associated_executor_is_unspecialised,-        void-      >::value-    >>-{-  template <typename H, typename F>-  co_spawn_state(H&& h, const Executor& ex, F&& f)-    : handler(std::forward<H>(h)),-      handler_work(ex),-      function(std::forward<F>(f))-  {-  }--  Handler handler;-  co_spawn_work_guard<Executor> handler_work;-  Function function;-};--struct co_spawn_dispatch-{-  template <typename CompletionToken>-  auto operator()(CompletionToken&& token) const-    -> decltype(asio::dispatch(std::forward<CompletionToken>(token)))-  {-    return asio::dispatch(std::forward<CompletionToken>(token));-  }-};--struct co_spawn_post+template <typename Executor>+inline co_spawn_work_guard<Executor>+make_co_spawn_work_guard(const Executor& ex) {-  template <typename CompletionToken>-  auto operator()(CompletionToken&& token) const-    -> decltype(asio::post(std::forward<CompletionToken>(token)))-  {-    return asio::post(std::forward<CompletionToken>(token));-  }-};+  return co_spawn_work_guard<Executor>(ex);+} -template <typename T, typename Handler, typename Executor, typename Function>+template <typename T, typename Executor, typename F, typename Handler> awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point(-    awaitable<T, Executor>*, co_spawn_state<Handler, Executor, Function> s)+    awaitable<T, Executor>*, Executor ex, F f, Handler handler) {-  (void) co_await co_spawn_dispatch{};+  auto spawn_work = make_co_spawn_work_guard(ex);+  auto handler_work = make_co_spawn_work_guard(+      asio::get_associated_executor(handler, ex)); +  (void) co_await (dispatch)(+      use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"});++  (co_await awaitable_thread_has_context_switched{}) = false;   std::exception_ptr e = nullptr;   bool done = false;-#if !defined(ASIO_NO_EXCEPTIONS)   try-#endif // !defined(ASIO_NO_EXCEPTIONS)   {-    T t = co_await s.function();+    T t = co_await f();      done = true; -    bool is_launching = (co_await awaitable_thread_is_launching{});-    if (is_launching)+    bool switched = (co_await awaitable_thread_has_context_switched{});+    if (!switched)     {-      co_await this_coro::throw_if_cancelled(false);-      (void) co_await co_spawn_post();+      (void) co_await (post)(+          use_awaitable_t<Executor>{__FILE__,+            __LINE__, "co_spawn_entry_point"});     } -    (dispatch)(s.handler_work.get_executor(),-        [handler = std::move(s.handler), t = std::move(t)]() mutable+    (dispatch)(handler_work.get_executor(),+        [handler = std::move(handler), t = std::move(t)]() mutable         {           std::move(handler)(std::exception_ptr(), std::move(t));         });      co_return;   }-#if !defined(ASIO_NO_EXCEPTIONS)   catch (...)   {     if (done)@@ -172,51 +119,52 @@      e = std::current_exception();   }-#endif // !defined(ASIO_NO_EXCEPTIONS) -  bool is_launching = (co_await awaitable_thread_is_launching{});-  if (is_launching)+  bool switched = (co_await awaitable_thread_has_context_switched{});+  if (!switched)   {-    co_await this_coro::throw_if_cancelled(false);-    (void) co_await co_spawn_post();+    (void) co_await (post)(+        use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"});   } -  (dispatch)(s.handler_work.get_executor(),-      [handler = std::move(s.handler), e]() mutable+  (dispatch)(handler_work.get_executor(),+      [handler = std::move(handler), e]() mutable       {         std::move(handler)(e, T());       }); } -template <typename Handler, typename Executor, typename Function>+template <typename Executor, typename F, typename Handler> awaitable<awaitable_thread_entry_point, Executor> co_spawn_entry_point(-    awaitable<void, Executor>*, co_spawn_state<Handler, Executor, Function> s)+    awaitable<void, Executor>*, Executor ex, F f, Handler handler) {-  (void) co_await co_spawn_dispatch{};+  auto spawn_work = make_co_spawn_work_guard(ex);+  auto handler_work = make_co_spawn_work_guard(+      asio::get_associated_executor(handler, ex)); +  (void) co_await (dispatch)(+      use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"});++  (co_await awaitable_thread_has_context_switched{}) = false;   std::exception_ptr e = nullptr;-#if !defined(ASIO_NO_EXCEPTIONS)   try-#endif // !defined(ASIO_NO_EXCEPTIONS)   {-    co_await s.function();+    co_await f();   }-#if !defined(ASIO_NO_EXCEPTIONS)   catch (...)   {     e = std::current_exception();   }-#endif // !defined(ASIO_NO_EXCEPTIONS) -  bool is_launching = (co_await awaitable_thread_is_launching{});-  if (is_launching)+  bool switched = (co_await awaitable_thread_has_context_switched{});+  if (!switched)   {-    co_await this_coro::throw_if_cancelled(false);-    (void) co_await co_spawn_post();+    (void) co_await (post)(+        use_awaitable_t<Executor>{__FILE__, __LINE__, "co_spawn_entry_point"});   } -  (dispatch)(s.handler_work.get_executor(),-      [handler = std::move(s.handler), e]() mutable+  (dispatch)(handler_work.get_executor(),+      [handler = std::move(handler), e]() mutable       {         std::move(handler)(e);       });@@ -245,38 +193,36 @@ { public:   co_spawn_cancellation_handler(const Handler&, const Executor& ex)-    : signal_(detail::allocate_shared<cancellation_signal>(-          detail::recycling_allocator<cancellation_signal,-            detail::thread_info_base::cancellation_signal_tag>())),-      ex_(ex)+    : ex_(ex)   {   }    cancellation_slot slot()   {-    return signal_->slot();+    return signal_.slot();   }    void operator()(cancellation_type_t type)   {-    shared_ptr<cancellation_signal> sig = signal_;+    cancellation_signal* sig = &signal_;     asio::dispatch(ex_, [sig, type]{ sig->emit(type); });   }  private:-  shared_ptr<cancellation_signal> signal_;+  cancellation_signal signal_;   Executor ex_; }; + template <typename Handler, typename Executor> class co_spawn_cancellation_handler<Handler, Executor,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_executor<Handler,           Executor>::asio_associated_executor_is_unspecialised,         void       >::value-    >>+    >::type> { public:   co_spawn_cancellation_handler(const Handler&, const Executor&)@@ -309,7 +255,7 @@   {   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return ex_;   }@@ -317,9 +263,8 @@   template <typename Handler, typename F>   void operator()(Handler&& handler, F&& f) const   {-    typedef result_of_t<F()> awaitable_type;-    typedef decay_t<Handler> handler_type;-    typedef decay_t<F> function_type;+    typedef typename result_of<F()>::type awaitable_type;+    typedef typename decay<Handler>::type handler_type;     typedef co_spawn_cancellation_handler<       handler_type, Executor> cancel_handler_type; @@ -336,8 +281,7 @@     cancellation_state cancel_state(proxy_slot);      auto a = (co_spawn_entry_point)(static_cast<awaitable_type*>(nullptr),-        co_spawn_state<handler_type, Executor, function_type>(-          std::forward<Handler>(handler), ex_, std::forward<F>(f)));+        ex_, std::forward<F>(f), std::forward<Handler>(handler));     awaitable_handler<executor_type, void>(std::move(a),         ex_, proxy_slot, cancel_state).launch();   }@@ -355,10 +299,10 @@     CompletionToken, void(std::exception_ptr, T)) co_spawn(const Executor& ex,     awaitable<T, AwaitableExecutor> a, CompletionToken&& token,-    constraint_t<+    typename constraint<       (is_executor<Executor>::value || execution::is_executor<Executor>::value)         && is_convertible<Executor, AwaitableExecutor>::value-    >)+    >::type) {   return async_initiate<CompletionToken, void(std::exception_ptr, T)>(       detail::initiate_co_spawn<AwaitableExecutor>(AwaitableExecutor(ex)),@@ -372,10 +316,10 @@     CompletionToken, void(std::exception_ptr)) co_spawn(const Executor& ex,     awaitable<void, AwaitableExecutor> a, CompletionToken&& token,-    constraint_t<+    typename constraint<       (is_executor<Executor>::value || execution::is_executor<Executor>::value)         && is_convertible<Executor, AwaitableExecutor>::value-    >)+    >::type) {   return async_initiate<CompletionToken, void(std::exception_ptr)>(       detail::initiate_co_spawn<AwaitableExecutor>(AwaitableExecutor(ex)),@@ -390,11 +334,11 @@     CompletionToken, void(std::exception_ptr, T)) co_spawn(ExecutionContext& ctx,     awaitable<T, AwaitableExecutor> a, CompletionToken&& token,-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value         && is_convertible<typename ExecutionContext::executor_type,           AwaitableExecutor>::value-    >)+    >::type) {   return (co_spawn)(ctx.get_executor(), std::move(a),       std::forward<CompletionToken>(token));@@ -407,11 +351,11 @@     CompletionToken, void(std::exception_ptr)) co_spawn(ExecutionContext& ctx,     awaitable<void, AwaitableExecutor> a, CompletionToken&& token,-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value         && is_convertible<typename ExecutionContext::executor_type,           AwaitableExecutor>::value-    >)+    >::type) {   return (co_spawn)(ctx.get_executor(), std::move(a),       std::forward<CompletionToken>(token));@@ -419,30 +363,30 @@  template <typename Executor, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<-      result_of_t<F()>>::type) CompletionToken>+      typename result_of<F()>::type>::type) CompletionToken> inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,-    typename detail::awaitable_signature<result_of_t<F()>>::type)+    typename detail::awaitable_signature<typename result_of<F()>::type>::type) co_spawn(const Executor& ex, F&& f, CompletionToken&& token,-    constraint_t<+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    >)+    >::type) {   return async_initiate<CompletionToken,-    typename detail::awaitable_signature<result_of_t<F()>>::type>(+    typename detail::awaitable_signature<typename result_of<F()>::type>::type>(       detail::initiate_co_spawn<-        typename result_of_t<F()>::executor_type>(ex),+        typename result_of<F()>::type::executor_type>(ex),       token, std::forward<F>(f)); }  template <typename ExecutionContext, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::awaitable_signature<-      result_of_t<F()>>::type) CompletionToken>+      typename result_of<F()>::type>::type) CompletionToken> inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,-    typename detail::awaitable_signature<result_of_t<F()>>::type)+    typename detail::awaitable_signature<typename result_of<F()>::type>::type) co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    >)+    >::type) {   return (co_spawn)(ctx.get_executor(), std::forward<F>(f),       std::forward<CompletionToken>(token));
− link/modules/asio-standalone/asio/include/asio/impl/config.hpp
@@ -1,102 +0,0 @@-//-// impl/config.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_IMPL_CONFIG_HPP-#define ASIO_IMPL_CONFIG_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/detail/config.hpp"-#include <cerrno>-#include <cstdlib>-#include <limits>-#include <stdexcept>--#include "asio/detail/push_options.hpp"--namespace asio {-namespace detail {--template <typename T>-T config_get(const config_service& service, const char* section,-    const char* key_name, T default_value, false_type /*is_bool*/)-{-  if (is_unsigned<T>::value)-  {-    char buf[std::numeric_limits<unsigned long long>::digits10-        + 1 /* sign */ + 1 /* partial digit */ + 1 /* NUL */];-    if (const char* str = service.get_value(-          section, key_name, buf, sizeof(buf)))-    {-      char* end = nullptr;-      errno = 0;-      unsigned long long result = std::strtoull(str, &end, 0);-      if (errno == ERANGE-          || result > static_cast<unsigned long long>(-            (std::numeric_limits<T>::max)()))-        detail::throw_exception(std::out_of_range("config out of range"));-      return static_cast<T>(result);-    }-  }-  else-  {-    char buf[std::numeric_limits<unsigned long long>::digits10-        + 1 /* sign */ + 1 /* partial digit */ + 1 /* NUL */];-    if (const char* str = service.get_value(-          section, key_name, buf, sizeof(buf)))-    {-      char* end = nullptr;-      errno = 0;-      long long result = std::strtoll(str, &end, 0);-      if (errno == ERANGE || result < (std::numeric_limits<T>::min)()-          || result > (std::numeric_limits<T>::max)())-        detail::throw_exception(std::out_of_range("config out of range"));-      return static_cast<T>(result);-    }-  }-  return default_value;-}--template <typename T>-T config_get(const config_service& service, const char* section,-    const char* key_name, T default_value, true_type /*is_bool*/)-{-  char buf[std::numeric_limits<unsigned long long>::digits10-      + 1 /* sign */ + 1 /* partial digit */ + 1 /* NUL */];-  if (const char* str = service.get_value(-        section, key_name, buf, sizeof(buf)))-  {-    char* end = nullptr;-    errno = 0;-    unsigned long long result = std::strtoll(str, &end, 0);-    if (errno == ERANGE || (result != 0 && result != 1))-      detail::throw_exception(std::out_of_range("config out of range"));-    return static_cast<T>(result != 0);-  }-  return default_value;-}--} // namespace detail--template <typename T>-constraint_t<is_integral<T>::value, T>-config::get(const char* section, const char* key_name, T default_value) const-{-  return detail::config_get(service_, section,-      key_name, default_value, is_same<T, bool>());-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMPL_CONFIG_HPP
− link/modules/asio-standalone/asio/include/asio/impl/config.ipp
@@ -1,345 +0,0 @@-//-// impl/config.ipp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_IMPL_CONFIG_IPP-#define ASIO_IMPL_CONFIG_IPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include "asio/config.hpp"-#include "asio/detail/concurrency_hint.hpp"-#include <cctype>-#include <cstdio>-#include <cstring>-#include <cstdlib>-#include <vector>-#include <utility>--#include "asio/detail/push_options.hpp"--namespace asio {--config_service::config_service(execution_context& ctx)-  : detail::execution_context_service_base<config_service>(ctx)-{-}--void config_service::shutdown()-{-}--const char* config_service::get_value(const char* /*section*/,-    const char* /*key_name*/, char* /*value*/, std::size_t /*value_len*/) const-{-  return nullptr;-}--namespace detail {--class config_from_concurrency_hint_service : public config_service-{-public:-  explicit config_from_concurrency_hint_service(-      execution_context& ctx, int concurrency_hint)-    : config_service(ctx),-      concurrency_hint_(concurrency_hint)-  {-  }--  const char* get_value(const char* section, const char* key_name,-      char* value, std::size_t value_len) const override-  {-    if (std::strcmp(section, "scheduler") == 0)-    {-      if (std::strcmp(key_name, "concurrency_hint") == 0)-      {-        if (ASIO_CONCURRENCY_HINT_IS_SPECIAL(concurrency_hint_))-        {-          return-            !ASIO_CONCURRENCY_HINT_IS_LOCKING(-              SCHEDULER, concurrency_hint_) ||-            !ASIO_CONCURRENCY_HINT_IS_LOCKING(-                REACTOR_IO, concurrency_hint_) ? "1" : "-1";-        }-        else-        {-          std::snprintf(value, value_len, "%d", concurrency_hint_);-          return value;-        }-      }-      else if (std::strcmp(key_name, "locking") == 0)-      {-        return ASIO_CONCURRENCY_HINT_IS_LOCKING(-            SCHEDULER, concurrency_hint_) ? "1" : "0";-      }-    }-    else if (std::strcmp(section, "reactor") == 0)-    {-      if (std::strcmp(key_name, "io_locking") == 0)-      {-        return ASIO_CONCURRENCY_HINT_IS_LOCKING(-            REACTOR_IO, concurrency_hint_) ? "1" : "0";-      }-      else if (std::strcmp(key_name, "registration_locking") == 0)-      {-        return ASIO_CONCURRENCY_HINT_IS_LOCKING(-            REACTOR_REGISTRATION, concurrency_hint_) ? "1" : "0";-      }-    }-    return nullptr;-  }--private:-  int concurrency_hint_;-};--} // namespace detail--config_from_concurrency_hint::config_from_concurrency_hint()-  : concurrency_hint_(ASIO_CONCURRENCY_HINT_DEFAULT)-{-}--void config_from_concurrency_hint::make(execution_context& ctx) const-{-  (void)make_service<detail::config_from_concurrency_hint_service>(ctx,-      concurrency_hint_ == 1-        ? ASIO_CONCURRENCY_HINT_1 : concurrency_hint_);-}--namespace detail {--class config_from_string_service : public config_service-{-public:-  config_from_string_service(execution_context& ctx,-      std::string s, std::string prefix)-    : config_service(ctx),-      string_(static_cast<std::string&&>(s)),-      prefix_(static_cast<std::string&&>(prefix))-  {-    enum-    {-      expecting_key_name,-      key_name,-      expecting_equals,-      expecting_value,-      value,-      expecting_eol-    } state = expecting_key_name;-    std::pair<const char*, const char*> entry{};--    for (char& c : string_)-    {-      switch (state)-      {-      case expecting_key_name:-        switch (c)-        {-        case ' ': case '\t': case '\n':-          break;-        case '#':-          state = expecting_eol;-          break;-        default:-          entry.first = &c;-          state = key_name;-          break;-        }-        break;-      case key_name:-        switch (c)-        {-        case ' ': case '\t':-          c = 0;-          state = expecting_equals;-          break;-        case '=':-          c = 0;-          state = expecting_value;-          break;-        case '\n':-          entry.first = nullptr;-          state = expecting_key_name;-          break;-        case '#':-          entry.first = nullptr;-          state = expecting_eol;-          break;-        default:-          break;-        }-        break;-      case expecting_equals:-        switch (c)-        {-        case ' ': case '\t':-          break;-        case '=':-          state = expecting_value;-          break;-        case '\n':-          entry.first = nullptr;-          state = expecting_key_name;-          break;-        default:-          entry.first = nullptr;-          state = expecting_eol;-          break;-        }-        break;-      case expecting_value:-        switch (c)-        {-        case ' ': case '\t':-          break;-        case '\n':-          entry.first = nullptr;-          state = expecting_key_name;-          break;-        case '#':-          entry.first = nullptr;-          state = expecting_eol;-          break;-        default:-          entry.second = &c;-          state = value;-          break;-        }-        break;-      case value:-        switch (c)-        {-        case '\n':-          c = 0;-          entries_.push_back(entry);-          entry.first = entry.second = nullptr;-          state = expecting_key_name;-          break;-        case '#':-          c = 0;-          entries_.push_back(entry);-          entry.first = entry.second = nullptr;-          state = expecting_eol;-          break;-        default:-          break;-        }-        break;-      case expecting_eol:-        switch (c)-        {-        case '\n':-          state = expecting_key_name;-          break;-        default:-          break;-        }-        break;-      }-    }-    if (entry.first && entry.second)-      entries_.push_back(entry);-  }--  const char* get_value(const char* section, const char* key_name,-      char* /*value*/, std::size_t /*value_len*/) const override-  {-    std::string entry_key;-    entry_key.reserve(prefix_.length() + 1-        + std::strlen(section) + 1-        + std::strlen(key_name) + 1);-    entry_key.append(prefix_);-    if (!entry_key.empty())-      entry_key.append(".");-    entry_key.append(section);-    entry_key.append(".");-    entry_key.append(key_name);-    for (const std::pair<const char*, const char*>& entry : entries_)-      if (entry_key == entry.first)-        return entry.second;-    return nullptr;-  }--private:-  std::string string_;-  std::string prefix_;-  std::vector<std::pair<const char*, const char*>> entries_;-};--} // namespace detail--void config_from_string::make(execution_context& ctx) const-{-  (void)make_service<detail::config_from_string_service>(ctx, string_, prefix_);-}--namespace detail {--#if defined(ASIO_MSVC)-# pragma warning (push)-# pragma warning (disable:4996) // suppress unsafe warning for std::getenv-#endif // defined(ASIO_MSVC)--class config_from_env_service : public config_service-{-public:-  explicit config_from_env_service(-      execution_context& ctx, std::string prefix)-    : config_service(ctx),-      prefix_(static_cast<std::string&&>(prefix))-  {-  }--  const char* get_value(const char* section, const char* key_name,-      char* /*value*/, std::size_t /*value_len*/) const override-  {-    std::string env_var;-    env_var.reserve(prefix_.length() + 1-        + std::strlen(section) + 1-        + std::strlen(key_name) + 1);-    env_var.append(prefix_);-    if (!env_var.empty())-      env_var.append("_");-    env_var.append(section);-    env_var.append("_");-    env_var.append(key_name);-    for (char& c : env_var)-      c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));-    return std::getenv(env_var.c_str());-  }--private:-  std::string prefix_;-};--#if defined(ASIO_MSVC)-# pragma warning (pop)-#endif // defined(ASIO_MSVC)--} // namespace detail--config_from_env::config_from_env()-  : prefix_("asio")-{-}--void config_from_env::make(execution_context& ctx) const-{-  (void)make_service<detail::config_from_env_service>(ctx, prefix_);-}--} // namespace asio--#include "asio/detail/pop_options.hpp"--#endif // ASIO_IMPL_CONFIG_IPP
link/modules/asio-standalone/asio/include/asio/impl/connect.hpp view
@@ -2,7 +2,7 @@ // impl/connect.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,7 +19,9 @@ #include "asio/associator.hpp" #include "asio/detail/base_from_cancellation_state.hpp" #include "asio/detail/bind_handler.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -34,6 +36,15 @@  namespace detail {+  struct default_connect_condition+  {+    template <typename Endpoint>+    bool operator()(const asio::error_code&, const Endpoint&)+    {+      return true;+    }+  };+   template <typename Protocol, typename Iterator>   inline typename Protocol::endpoint deref_connect_result(       Iterator iter, asio::error_code& ec)@@ -41,15 +52,38 @@     return ec ? typename Protocol::endpoint() : *iter;   } +  template <typename T, typename Iterator>+  struct legacy_connect_condition_helper : T+  {+    typedef char (*fallback_func_type)(...);+    operator fallback_func_type() const;+  };++  template <typename R, typename Arg1, typename Arg2, typename Iterator>+  struct legacy_connect_condition_helper<R (*)(Arg1, Arg2), Iterator>+  {+    R operator()(Arg1, Arg2) const;+    char operator()(...) const;+  };++  template <typename T, typename Iterator>+  struct is_legacy_connect_condition+  {+    static char asio_connect_condition_check(char);+    static char (&asio_connect_condition_check(Iterator))[2];++    static const bool value =+      sizeof(asio_connect_condition_check(+        (declval<legacy_connect_condition_helper<T, Iterator> >())(+          declval<const asio::error_code>(),+          declval<const Iterator>()))) != 1;+  };+   template <typename ConnectCondition, typename Iterator>   inline Iterator call_connect_condition(ConnectCondition& connect_condition,       const asio::error_code& ec, Iterator next, Iterator end,-      constraint_t<-        is_same<-          result_of_t<ConnectCondition(asio::error_code, Iterator)>,-          Iterator-        >::value-      > = 0)+      typename enable_if<is_legacy_connect_condition<+        ConnectCondition, Iterator>::value>::type* = 0)   {     if (next != end)       return connect_condition(ec, next);@@ -59,27 +93,21 @@   template <typename ConnectCondition, typename Iterator>   inline Iterator call_connect_condition(ConnectCondition& connect_condition,       const asio::error_code& ec, Iterator next, Iterator end,-      constraint_t<-        is_same<-          result_of_t<ConnectCondition(asio::error_code,-            decltype(*declval<Iterator>()))>,-          bool-        >::value-      > = 0)+      typename enable_if<!is_legacy_connect_condition<+        ConnectCondition, Iterator>::value>::type* = 0)   {     for (;next != end; ++next)       if (connect_condition(ec, *next))         return next;     return end;   }-} // namespace detail+}  template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints,-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    >)+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type) {   asio::error_code ec;   typename Protocol::endpoint result = connect(s, endpoints, ec);@@ -90,16 +118,35 @@ template <typename Protocol, typename Executor, typename EndpointSequence> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints, asio::error_code& ec,-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    >)+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type) {   return detail::deref_connect_result<Protocol>(       connect(s, endpoints.begin(), endpoints.end(),         detail::default_connect_condition(), ec), ec); } +#if !defined(ASIO_NO_DEPRECATED) template <typename Protocol, typename Executor, typename Iterator>+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+{+  asio::error_code ec;+  Iterator result = connect(s, begin, ec);+  asio::detail::throw_error(ec, "connect");+  return result;+}++template <typename Protocol, typename Executor, typename Iterator>+inline Iterator connect(basic_socket<Protocol, Executor>& s,+    Iterator begin, asio::error_code& ec,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+{+  return connect(s, begin, Iterator(), detail::default_connect_condition(), ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Protocol, typename Executor, typename Iterator> Iterator connect(basic_socket<Protocol, Executor>& s,     Iterator begin, Iterator end) {@@ -120,13 +167,8 @@     typename EndpointSequence, typename ConnectCondition> typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints, ConnectCondition connect_condition,-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    >,-    constraint_t<-      is_connect_condition<ConnectCondition,-        decltype(declval<const EndpointSequence&>().begin())>::value-    >)+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type) {   asio::error_code ec;   typename Protocol::endpoint result = connect(@@ -140,26 +182,42 @@ typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,     const EndpointSequence& endpoints, ConnectCondition connect_condition,     asio::error_code& ec,-    constraint_t<-      is_endpoint_sequence<EndpointSequence>::value-    >,-    constraint_t<-      is_connect_condition<ConnectCondition,-        decltype(declval<const EndpointSequence&>().begin())>::value-    >)+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type) {   return detail::deref_connect_result<Protocol>(       connect(s, endpoints.begin(), endpoints.end(),         connect_condition, ec), ec); } +#if !defined(ASIO_NO_DEPRECATED) template <typename Protocol, typename Executor,     typename Iterator, typename ConnectCondition>+Iterator connect(basic_socket<Protocol, Executor>& s,+    Iterator begin, ConnectCondition connect_condition,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+{+  asio::error_code ec;+  Iterator result = connect(s, begin, connect_condition, ec);+  asio::detail::throw_error(ec, "connect");+  return result;+}++template <typename Protocol, typename Executor,+    typename Iterator, typename ConnectCondition>+inline Iterator connect(basic_socket<Protocol, Executor>& s,+    Iterator begin, ConnectCondition connect_condition,+    asio::error_code& ec,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+{+  return connect(s, begin, Iterator(), connect_condition, ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Protocol, typename Executor,+    typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,-    Iterator end, ConnectCondition connect_condition,-    constraint_t<-      is_connect_condition<ConnectCondition, Iterator>::value-    >)+    Iterator end, ConnectCondition connect_condition) {   asio::error_code ec;   Iterator result = connect(s, begin, end, connect_condition, ec);@@ -171,10 +229,7 @@     typename Iterator, typename ConnectCondition> Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,     Iterator end, ConnectCondition connect_condition,-    asio::error_code& ec,-    constraint_t<-      is_connect_condition<ConnectCondition, Iterator>::value-    >)+    asio::error_code& ec) {   ec = asio::error_code(); @@ -256,10 +311,11 @@         endpoints_(endpoints),         index_(0),         start_(0),-        handler_(static_cast<RangeConnectHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(RangeConnectHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     range_connect_op(const range_connect_op& other)       : base_from_cancellation_state<RangeConnectHandler>(other),         base_from_connect_condition<ConnectCondition>(other),@@ -273,16 +329,17 @@      range_connect_op(range_connect_op&& other)       : base_from_cancellation_state<RangeConnectHandler>(-          static_cast<base_from_cancellation_state<RangeConnectHandler>&&>(-            other)),+          ASIO_MOVE_CAST(base_from_cancellation_state<+            RangeConnectHandler>)(other)),         base_from_connect_condition<ConnectCondition>(other),         socket_(other.socket_),         endpoints_(other.endpoints_),         index_(other.index_),         start_(other.start_),-        handler_(static_cast<RangeConnectHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(RangeConnectHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(asio::error_code ec, int start = 0)     {@@ -312,7 +369,7 @@             socket_.close(ec);             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));             socket_.async_connect(*iter,-                static_cast<range_connect_op&&>(*this));+                ASIO_MOVE_CAST(range_connect_op)(*this));             return;           } @@ -322,7 +379,7 @@             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));             asio::post(socket_.get_executor(),                 detail::bind_handler(-                  static_cast<range_connect_op&&>(*this), ec));+                  ASIO_MOVE_CAST(range_connect_op)(*this), ec));             return;           } @@ -350,7 +407,7 @@           ++index_;         } -        static_cast<RangeConnectHandler&&>(handler_)(+        ASIO_MOVE_OR_LVALUE(RangeConnectHandler)(handler_)(             static_cast<const asio::error_code&>(ec),             static_cast<const typename Protocol::endpoint&>(               ec || iter == end ? typename Protocol::endpoint() : *iter));@@ -366,6 +423,36 @@    template <typename Protocol, typename Executor, typename EndpointSequence,       typename ConnectCondition, typename RangeConnectHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      range_connect_op<Protocol, Executor, EndpointSequence,+        ConnectCondition, RangeConnectHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Protocol, typename Executor, typename EndpointSequence,+      typename ConnectCondition, typename RangeConnectHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      range_connect_op<Protocol, Executor, EndpointSequence,+        ConnectCondition, RangeConnectHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Protocol, typename Executor, typename EndpointSequence,+      typename ConnectCondition, typename RangeConnectHandler>   inline bool asio_handler_is_continuation(       range_connect_op<Protocol, Executor, EndpointSequence,         ConnectCondition, RangeConnectHandler>* this_handler)@@ -374,6 +461,36 @@         this_handler->handler_);   } +  template <typename Function, typename Executor, typename Protocol,+      typename EndpointSequence, typename ConnectCondition,+      typename RangeConnectHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      range_connect_op<Protocol, Executor, EndpointSequence,+        ConnectCondition, RangeConnectHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename Executor, typename Protocol,+      typename EndpointSequence, typename ConnectCondition,+      typename RangeConnectHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      range_connect_op<Protocol, Executor, EndpointSequence,+        ConnectCondition, RangeConnectHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename Protocol, typename Executor>   class initiate_async_range_connect   {@@ -385,14 +502,14 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return socket_.get_executor();     }      template <typename RangeConnectHandler,         typename EndpointSequence, typename ConnectCondition>-    void operator()(RangeConnectHandler&& handler,+    void operator()(ASIO_MOVE_ARG(RangeConnectHandler) handler,         const EndpointSequence& endpoints,         const ConnectCondition& connect_condition) const     {@@ -404,7 +521,7 @@        non_const_lvalue<RangeConnectHandler> handler2(handler);       range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition,-        decay_t<RangeConnectHandler>>(socket_, endpoints,+        typename decay<RangeConnectHandler>::type>(socket_, endpoints,           connect_condition, handler2.value)(asio::error_code(), 1);     } @@ -430,10 +547,11 @@         iter_(begin),         end_(end),         start_(0),-        handler_(static_cast<IteratorConnectHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     iterator_connect_op(const iterator_connect_op& other)       : base_from_cancellation_state<IteratorConnectHandler>(other),         base_from_connect_condition<ConnectCondition>(other),@@ -447,16 +565,17 @@      iterator_connect_op(iterator_connect_op&& other)       : base_from_cancellation_state<IteratorConnectHandler>(-          static_cast<base_from_cancellation_state<IteratorConnectHandler>&&>(-            other)),+          ASIO_MOVE_CAST(base_from_cancellation_state<+            IteratorConnectHandler>)(other)),         base_from_connect_condition<ConnectCondition>(other),         socket_(other.socket_),         iter_(other.iter_),         end_(other.end_),         start_(other.start_),-        handler_(static_cast<IteratorConnectHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(IteratorConnectHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(asio::error_code ec, int start = 0)     {@@ -472,7 +591,7 @@             socket_.close(ec);             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));             socket_.async_connect(*iter_,-                static_cast<iterator_connect_op&&>(*this));+                ASIO_MOVE_CAST(iterator_connect_op)(*this));             return;           } @@ -482,7 +601,7 @@             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_connect"));             asio::post(socket_.get_executor(),                 detail::bind_handler(-                  static_cast<iterator_connect_op&&>(*this), ec));+                  ASIO_MOVE_CAST(iterator_connect_op)(*this), ec));             return;           } @@ -509,7 +628,7 @@           ++iter_;         } -        static_cast<IteratorConnectHandler&&>(handler_)(+        ASIO_MOVE_OR_LVALUE(IteratorConnectHandler)(handler_)(             static_cast<const asio::error_code&>(ec),             static_cast<const Iterator&>(iter_));       }@@ -525,6 +644,36 @@    template <typename Protocol, typename Executor, typename Iterator,       typename ConnectCondition, typename IteratorConnectHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      iterator_connect_op<Protocol, Executor, Iterator,+        ConnectCondition, IteratorConnectHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Protocol, typename Executor, typename Iterator,+      typename ConnectCondition, typename IteratorConnectHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      iterator_connect_op<Protocol, Executor, Iterator,+        ConnectCondition, IteratorConnectHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Protocol, typename Executor, typename Iterator,+      typename ConnectCondition, typename IteratorConnectHandler>   inline bool asio_handler_is_continuation(       iterator_connect_op<Protocol, Executor, Iterator,         ConnectCondition, IteratorConnectHandler>* this_handler)@@ -533,6 +682,36 @@         this_handler->handler_);   } +  template <typename Function, typename Executor, typename Protocol,+      typename Iterator, typename ConnectCondition,+      typename IteratorConnectHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      iterator_connect_op<Protocol, Executor, Iterator,+        ConnectCondition, IteratorConnectHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename Executor, typename Protocol,+      typename Iterator, typename ConnectCondition,+      typename IteratorConnectHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      iterator_connect_op<Protocol, Executor, Iterator,+        ConnectCondition, IteratorConnectHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename Protocol, typename Executor>   class initiate_async_iterator_connect   {@@ -545,14 +724,14 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return socket_.get_executor();     }      template <typename IteratorConnectHandler,         typename Iterator, typename ConnectCondition>-    void operator()(IteratorConnectHandler&& handler,+    void operator()(ASIO_MOVE_ARG(IteratorConnectHandler) handler,         Iterator begin, Iterator end,         const ConnectCondition& connect_condition) const     {@@ -564,7 +743,7 @@        non_const_lvalue<IteratorConnectHandler> handler2(handler);       iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition,-        decay_t<IteratorConnectHandler>>(socket_, begin, end,+        typename decay<IteratorConnectHandler>::type>(socket_, begin, end,           connect_condition, handler2.value)(asio::error_code(), 1);     } @@ -585,20 +764,21 @@     DefaultCandidate>   : Associator<RangeConnectHandler, DefaultCandidate> {-  static typename Associator<RangeConnectHandler, DefaultCandidate>::type get(-      const detail::range_connect_op<Protocol, Executor, EndpointSequence,-        ConnectCondition, RangeConnectHandler>& h) noexcept+  static typename Associator<RangeConnectHandler, DefaultCandidate>::type+  get(const detail::range_connect_op<Protocol, Executor, EndpointSequence,+        ConnectCondition, RangeConnectHandler>& h) ASIO_NOEXCEPT   {     return Associator<RangeConnectHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::range_connect_op<Protocol, Executor,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<RangeConnectHandler, DefaultCandidate>::type)+  get(const detail::range_connect_op<Protocol, Executor,         EndpointSequence, ConnectCondition, RangeConnectHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((       Associator<RangeConnectHandler, DefaultCandidate>::get(-        h.handler_, c))+        h.handler_, c)))   {     return Associator<RangeConnectHandler, DefaultCandidate>::get(         h.handler_, c);@@ -617,19 +797,20 @@ {   static typename Associator<IteratorConnectHandler, DefaultCandidate>::type   get(const detail::iterator_connect_op<Protocol, Executor, Iterator,-        ConnectCondition, IteratorConnectHandler>& h) noexcept+        ConnectCondition, IteratorConnectHandler>& h) ASIO_NOEXCEPT   {     return Associator<IteratorConnectHandler, DefaultCandidate>::get(         h.handler_);   } -  static auto get(-      const detail::iterator_connect_op<Protocol, Executor,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<IteratorConnectHandler, DefaultCandidate>::type)+  get(const detail::iterator_connect_op<Protocol, Executor,         Iterator, ConnectCondition, IteratorConnectHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((       Associator<IteratorConnectHandler, DefaultCandidate>::get(-        h.handler_, c))+        h.handler_, c)))   {     return Associator<IteratorConnectHandler, DefaultCandidate>::get(         h.handler_, c);@@ -637,6 +818,139 @@ };  #endif // !defined(GENERATING_DOCUMENTATION)++template <typename Protocol, typename Executor, typename EndpointSequence,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      typename Protocol::endpoint)) RangeConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,+    void (asio::error_code, typename Protocol::endpoint))+async_connect(basic_socket<Protocol, Executor>& s,+    const EndpointSequence& endpoints,+    ASIO_MOVE_ARG(RangeConnectToken) token,+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<RangeConnectToken,+      void (asio::error_code, typename Protocol::endpoint)>(+        declval<detail::initiate_async_range_connect<Protocol, Executor> >(),+        token, endpoints, declval<detail::default_connect_condition>())))+{+  return async_initiate<RangeConnectToken,+    void (asio::error_code, typename Protocol::endpoint)>(+      detail::initiate_async_range_connect<Protocol, Executor>(s),+      token, endpoints, detail::default_connect_condition());+}++#if !defined(ASIO_NO_DEPRECATED)+template <typename Protocol, typename Executor, typename Iterator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      Iterator)) IteratorConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+    void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+    ASIO_MOVE_ARG(IteratorConnectToken) token,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<IteratorConnectToken,+      void (asio::error_code, Iterator)>(+        declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+        token, begin, Iterator(),+        declval<detail::default_connect_condition>())))+{+  return async_initiate<IteratorConnectToken,+    void (asio::error_code, Iterator)>(+      detail::initiate_async_iterator_connect<Protocol, Executor>(s),+      token, begin, Iterator(),+      detail::default_connect_condition());+}+#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Protocol, typename Executor, typename Iterator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      Iterator)) IteratorConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+    void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,+    ASIO_MOVE_ARG(IteratorConnectToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<IteratorConnectToken,+      void (asio::error_code, Iterator)>(+        declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+        token, begin, end, declval<detail::default_connect_condition>())))+{+  return async_initiate<IteratorConnectToken,+    void (asio::error_code, Iterator)>(+      detail::initiate_async_iterator_connect<Protocol, Executor>(s),+      token, begin, end, detail::default_connect_condition());+}++template <typename Protocol, typename Executor,+    typename EndpointSequence, typename ConnectCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      typename Protocol::endpoint)) RangeConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(RangeConnectToken,+    void (asio::error_code, typename Protocol::endpoint))+async_connect(basic_socket<Protocol, Executor>& s,+    const EndpointSequence& endpoints, ConnectCondition connect_condition,+    ASIO_MOVE_ARG(RangeConnectToken) token,+    typename constraint<is_endpoint_sequence<+        EndpointSequence>::value>::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<RangeConnectToken,+      void (asio::error_code, typename Protocol::endpoint)>(+        declval<detail::initiate_async_range_connect<Protocol, Executor> >(),+        token, endpoints, connect_condition)))+{+  return async_initiate<RangeConnectToken,+    void (asio::error_code, typename Protocol::endpoint)>(+      detail::initiate_async_range_connect<Protocol, Executor>(s),+      token, endpoints, connect_condition);+}++#if !defined(ASIO_NO_DEPRECATED)+template <typename Protocol, typename Executor,+    typename Iterator, typename ConnectCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      Iterator)) IteratorConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+    void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+    ConnectCondition connect_condition,+    ASIO_MOVE_ARG(IteratorConnectToken) token,+    typename constraint<!is_endpoint_sequence<Iterator>::value>::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<IteratorConnectToken,+      void (asio::error_code, Iterator)>(+        declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+        token, begin, Iterator(), connect_condition)))+{+  return async_initiate<IteratorConnectToken,+    void (asio::error_code, Iterator)>(+      detail::initiate_async_iterator_connect<Protocol, Executor>(s),+      token, begin, Iterator(), connect_condition);+}+#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Protocol, typename Executor,+    typename Iterator, typename ConnectCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      Iterator)) IteratorConnectToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(IteratorConnectToken,+    void (asio::error_code, Iterator))+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,+    Iterator end, ConnectCondition connect_condition,+    ASIO_MOVE_ARG(IteratorConnectToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<IteratorConnectToken,+      void (asio::error_code, Iterator)>(+        declval<detail::initiate_async_iterator_connect<Protocol, Executor> >(),+        token, begin, end, connect_condition)))+{+  return async_initiate<IteratorConnectToken,+    void (asio::error_code, Iterator)>(+      detail::initiate_async_iterator_connect<Protocol, Executor>(s),+      token, begin, end, connect_condition);+}  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/impl/connect_pipe.hpp view
@@ -2,7 +2,7 @@ // impl/connect_pipe.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/impl/connect_pipe.ipp view
@@ -2,7 +2,7 @@ // impl/connect_pipe.ipp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2021 Klemens D. Morgenstern //                    (klemens dot morgenstern at gmx dot net) //@@ -62,9 +62,8 @@   _snwprintf( #endif // defined(ASIO_HAS_SECURE_RTL)       pipe_name, 128,-      // Include address of static to discriminate asio instances in DLLs.-      L"\\\\.\\pipe\\asio-A0812896-741A-484D-AF23-BE51BF620E22-%u-%p-%ld-%ld",-      static_cast<unsigned int>(::GetCurrentProcessId()), &counter1, n1, n2);+      L"\\\\.\\pipe\\asio-A0812896-741A-484D-AF23-BE51BF620E22-%u-%ld-%ld",+      static_cast<unsigned int>(::GetCurrentProcessId()), n1, n2);    p[0] = ::CreateNamedPipeW(pipe_name,       PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
link/modules/asio-standalone/asio/include/asio/impl/consign.hpp view
@@ -2,7 +2,7 @@ // impl/consign.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,12 +16,15 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp" @@ -36,16 +39,17 @@   typedef void result_type;    template <typename H>-  consign_handler(H&& handler, std::tuple<Values...> values)-    : handler_(static_cast<H&&>(handler)),-      values_(static_cast<std::tuple<Values...>&&>(values))+  consign_handler(ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)+    : handler_(ASIO_MOVE_CAST(H)(handler)),+      values_(ASIO_MOVE_CAST(std::tuple<Values...>)(values))   {   }    template <typename... Args>-  void operator()(Args&&... args)+  void operator()(ASIO_MOVE_ARG(Args)... args)   {-    static_cast<Handler&&>(handler_)(static_cast<Args&&>(args)...);+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        ASIO_MOVE_CAST(Args)(args)...);   }  //private:@@ -54,6 +58,32 @@ };  template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    consign_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    consign_handler<Handler>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation(     consign_handler<Handler>* this_handler) {@@ -61,57 +91,82 @@       this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    consign_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    consign_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ } // namespace detail  #if !defined(GENERATING_DOCUMENTATION)  template <typename CompletionToken, typename... Values, typename... Signatures>-struct async_result<consign_t<CompletionToken, Values...>, Signatures...>+struct async_result<+    consign_t<CompletionToken, Values...>, Signatures...>   : async_result<CompletionToken, Signatures...> {   template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;--    template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        std::tuple<Values...> values, Args&&... args) &&+    init_wrapper(Initiation init)+      : initiation_(ASIO_MOVE_CAST(Initiation)(init))     {-      static_cast<Initiation&&>(*this)(-          detail::consign_handler<decay_t<Handler>, Values...>(-            static_cast<Handler&&>(handler),-            static_cast<std::tuple<Values...>&&>(values)),-          static_cast<Args&&>(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        std::tuple<Values...> values, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        std::tuple<Values...> values,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<const Initiation&>(*this)(-          detail::consign_handler<decay_t<Handler>, Values...>(-            static_cast<Handler&&>(handler),-            static_cast<std::tuple<Values...>&&>(values)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          detail::consign_handler<+            typename decay<Handler>::type, Values...>(+              ASIO_MOVE_CAST(Handler)(handler),+              ASIO_MOVE_CAST(std::tuple<Values...>)(values)),+          ASIO_MOVE_CAST(Args)(args)...);     }++    Initiation initiation_;   };    template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<CompletionToken, Signatures...>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.token_, static_cast<std::tuple<Values...>&&>(token.values_),-        static_cast<Args&&>(args)...))+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signatures...,+      (async_initiate<CompletionToken, Signatures...>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<CompletionToken&>(),+        declval<std::tuple<Values...> >(),+        declval<ASIO_MOVE_ARG(Args)>()...)))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)   {     return async_initiate<CompletionToken, Signatures...>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.token_, static_cast<std::tuple<Values...>&&>(token.values_),-        static_cast<Args&&>(args)...);+        init_wrapper<typename decay<Initiation>::type>(+          ASIO_MOVE_CAST(Initiation)(initiation)),+        token.token_,+        ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),+        ASIO_MOVE_CAST(Args)(args)...);   } }; @@ -121,15 +176,18 @@     detail::consign_handler<Handler, Values...>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::consign_handler<Handler, Values...>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::consign_handler<Handler, Values...>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::consign_handler<Handler, Values...>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::consign_handler<Handler, Values...>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }
link/modules/asio-standalone/asio/include/asio/impl/deferred.hpp view
@@ -2,7 +2,7 @@ // impl/deferred.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -27,13 +27,15 @@ public:   template <typename Initiation, typename... InitArgs>   static deferred_async_operation<Signature, Initiation, InitArgs...>-  initiate(Initiation&& initiation, deferred_t, InitArgs&&... args)+  initiate(ASIO_MOVE_ARG(Initiation) initiation,+      deferred_t, ASIO_MOVE_ARG(InitArgs)... args)   {-    return deferred_async_operation<Signature, Initiation, InitArgs...>(-        deferred_init_tag{},-        static_cast<Initiation&&>(initiation),-        static_cast<InitArgs&&>(args)...);-  }+    return deferred_async_operation<+        Signature, Initiation, InitArgs...>(+          deferred_init_tag{},+          ASIO_MOVE_CAST(Initiation)(initiation),+          ASIO_MOVE_CAST(InitArgs)(args)...);+    } };  template <typename... Signatures>@@ -43,14 +45,15 @@   template <typename Initiation, typename... InitArgs>   static deferred_async_operation<       deferred_signatures<Signatures...>, Initiation, InitArgs...>-  initiate(Initiation&& initiation, deferred_t, InitArgs&&... args)+  initiate(ASIO_MOVE_ARG(Initiation) initiation,+      deferred_t, ASIO_MOVE_ARG(InitArgs)... args)   {     return deferred_async_operation<         deferred_signatures<Signatures...>, Initiation, InitArgs...>(           deferred_init_tag{},-          static_cast<Initiation&&>(initiation),-          static_cast<InitArgs&&>(args)...);-  }+          ASIO_MOVE_CAST(Initiation)(initiation),+          ASIO_MOVE_CAST(InitArgs)(args)...);+    } };  template <typename Function, typename Signature>@@ -58,8 +61,9 @@ { public:   template <typename Initiation, typename... InitArgs>-  static auto initiate(Initiation&& initiation,-      deferred_function<Function> token, InitArgs&&... init_args)+  static auto initiate(ASIO_MOVE_ARG(Initiation) initiation,+      deferred_function<Function> token,+      ASIO_MOVE_ARG(InitArgs)... init_args)     -> decltype(         deferred_sequence<           deferred_async_operation<@@ -68,9 +72,9 @@             deferred_async_operation<               Signature, Initiation, InitArgs...>(                 deferred_init_tag{},-                static_cast<Initiation&&>(initiation),-                static_cast<InitArgs&&>(init_args)...),-            static_cast<Function&&>(token.function_)))+                ASIO_MOVE_CAST(Initiation)(initiation),+                ASIO_MOVE_CAST(InitArgs)(init_args)...),+            ASIO_MOVE_CAST(Function)(token.function_)))   {     return deferred_sequence<         deferred_async_operation<@@ -79,9 +83,9 @@           deferred_async_operation<             Signature, Initiation, InitArgs...>(               deferred_init_tag{},-              static_cast<Initiation&&>(initiation),-              static_cast<InitArgs&&>(init_args)...),-          static_cast<Function&&>(token.function_));+              ASIO_MOVE_CAST(Initiation)(initiation),+              ASIO_MOVE_CAST(InitArgs)(init_args)...),+          ASIO_MOVE_CAST(Function)(token.function_));   } }; @@ -90,8 +94,9 @@ { public:   template <typename Initiation, typename... InitArgs>-  static auto initiate(Initiation&& initiation,-      deferred_function<Function> token, InitArgs&&... init_args)+  static auto initiate(ASIO_MOVE_ARG(Initiation) initiation,+      deferred_function<Function> token,+      ASIO_MOVE_ARG(InitArgs)... init_args)     -> decltype(         deferred_sequence<           deferred_async_operation<@@ -100,9 +105,9 @@             deferred_async_operation<               deferred_signatures<Signatures...>, Initiation, InitArgs...>(                 deferred_init_tag{},-                static_cast<Initiation&&>(initiation),-                static_cast<InitArgs&&>(init_args)...),-            static_cast<Function&&>(token.function_)))+                ASIO_MOVE_CAST(Initiation)(initiation),+                ASIO_MOVE_CAST(InitArgs)(init_args)...),+            ASIO_MOVE_CAST(Function)(token.function_)))   {     return deferred_sequence<         deferred_async_operation<@@ -111,9 +116,9 @@           deferred_async_operation<             deferred_signatures<Signatures...>, Initiation, InitArgs...>(               deferred_init_tag{},-              static_cast<Initiation&&>(initiation),-              static_cast<InitArgs&&>(init_args)...),-          static_cast<Function&&>(token.function_));+              ASIO_MOVE_CAST(Initiation)(initiation),+              ASIO_MOVE_CAST(InitArgs)(init_args)...),+          ASIO_MOVE_CAST(Function)(token.function_));   } }; @@ -124,15 +129,19 @@     DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::deferred_sequence_handler<Handler, Tail>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::deferred_sequence_handler<Handler, Tail>& h)+    ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::deferred_sequence_handler<Handler, Tail>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::deferred_sequence_handler<Handler, Tail>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }
link/modules/asio-standalone/asio/include/asio/impl/detached.hpp view
@@ -2,7 +2,7 @@ // impl/detached.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,6 +17,7 @@  #include "asio/detail/config.hpp" #include "asio/async_result.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp" @@ -33,18 +34,37 @@     {     } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+     template <typename... Args>     void operator()(Args...)     {     }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    void operator()()+    {+    }++#define ASIO_PRIVATE_DETACHED_DEF(n) \+    template <ASIO_VARIADIC_TPARAMS(n)> \+    void operator()(ASIO_VARIADIC_TARGS(n)) \+    { \+    } \+    /**/+    ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_DETACHED_DEF)+#undef ASIO_PRIVATE_DETACHED_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)   };  } // namespace detail  #if !defined(GENERATING_DOCUMENTATION) -template <typename... Signatures>-struct async_result<detached_t, Signatures...>+template <typename Signature>+struct async_result<detached_t, Signature> {   typedef asio::detail::detached_handler completion_handler_type; @@ -58,14 +78,47 @@   {   } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename Initiation, typename RawCompletionToken, typename... Args>-  static return_type initiate(Initiation&& initiation,-      RawCompletionToken&&, Args&&... args)+  static return_type initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken),+      ASIO_MOVE_ARG(Args)... args)   {-    static_cast<Initiation&&>(initiation)(+    ASIO_MOVE_CAST(Initiation)(initiation)(         detail::detached_handler(detached_t()),-        static_cast<Args&&>(args)...);+        ASIO_MOVE_CAST(Args)(args)...);   }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename Initiation, typename RawCompletionToken>+  static return_type initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken))+  {+    ASIO_MOVE_CAST(Initiation)(initiation)(+        detail::detached_handler(detached_t()));+  }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, typename RawCompletionToken, \+      ASIO_VARIADIC_TPARAMS(n)> \+  static return_type initiate( \+      ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_MOVE_ARG(RawCompletionToken), \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    ASIO_MOVE_CAST(Initiation)(initiation)( \+        detail::detached_handler(detached_t()), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) };  #endif // !defined(GENERATING_DOCUMENTATION)
link/modules/asio-standalone/asio/include/asio/impl/error.ipp view
@@ -2,7 +2,7 @@ // impl/error.ipp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -31,7 +31,7 @@ class netdb_category : public asio::error_category { public:-  const char* name() const noexcept+  const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT   {     return "asio.netdb";   }@@ -63,7 +63,7 @@ class addrinfo_category : public asio::error_category { public:-  const char* name() const noexcept+  const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT   {     return "asio.addrinfo";   }@@ -93,7 +93,7 @@ class misc_category : public asio::error_category { public:-  const char* name() const noexcept+  const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT   {     return "asio.misc";   }
link/modules/asio-standalone/asio/include/asio/impl/error_code.ipp view
@@ -2,7 +2,7 @@ // impl/error_code.ipp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -37,7 +37,7 @@ class system_category : public error_category { public:-  const char* name() const noexcept+  const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT   {     return "asio.system";   }@@ -108,7 +108,7 @@  #if defined(ASIO_HAS_STD_ERROR_CODE)   std::error_condition default_error_condition(-      int ev) const noexcept+      int ev) const ASIO_ERROR_CATEGORY_NOEXCEPT   {     switch (ev)     {@@ -182,7 +182,6 @@       return std::errc::operation_would_block;     default:       return std::make_error_condition(ev, *this);-    }   } #endif // defined(ASIO_HAS_STD_ERROR_CODE) 
link/modules/asio-standalone/asio/include/asio/impl/execution_context.hpp view
@@ -2,7 +2,7 @@ // impl/execution_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -15,83 +15,14 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <cstring> #include "asio/detail/handler_type_requirements.hpp"-#include "asio/detail/memory.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/service_registry.hpp"-#include "asio/detail/throw_exception.hpp"  #include "asio/detail/push_options.hpp"  namespace asio { -template <typename Allocator>-execution_context::execution_context(allocator_arg_t, const Allocator& a)-  : execution_context(detail::allocate_object<allocator_impl<Allocator>>(a, a))-{-}--template <typename Allocator>-execution_context::execution_context(allocator_arg_t, const Allocator& a,-    const service_maker& initial_services)-  : execution_context(detail::allocate_object<allocator_impl<Allocator>>(a, a),-      initial_services)-{-}--inline execution_context::auto_allocator_ptr::~auto_allocator_ptr()-{-  ptr_->destroy();-}--template <typename Allocator>-void execution_context::allocator_impl<Allocator>::destroy()-{-  detail::deallocate_object(allocator_, this);-}--template <typename Allocator>-void* execution_context::allocator_impl<Allocator>::allocate(-    std::size_t size, std::size_t align)-{-  typename std::allocator_traits<Allocator>::template-    rebind_alloc<unsigned char> alloc(allocator_);--  std::size_t space = size + align - 1;-  unsigned char* base = std::allocator_traits<decltype(alloc)>::allocate(-      alloc, space + sizeof(std::ptrdiff_t));--  void* p = base;-  if (detail::align(align, size, p, space))-  {-    std::ptrdiff_t off = static_cast<unsigned char*>(p) - base;-    std::memcpy(static_cast<unsigned char*>(p) + size, &off, sizeof(off));-    return p;-  }--  std::bad_alloc ex;-  asio::detail::throw_exception(ex);-  return 0;-}--template <typename Allocator>-void execution_context::allocator_impl<Allocator>::deallocate(-    void* ptr, std::size_t size, std::size_t align)-{-  if (ptr)-  {-    typename std::allocator_traits<Allocator>::template-      rebind_alloc<unsigned char> alloc(allocator_);--    std::ptrdiff_t off;-    std::memcpy(&off, static_cast<unsigned char*>(ptr) + size, sizeof(off));-    unsigned char* base = static_cast<unsigned char*>(ptr) - off;--    std::allocator_traits<decltype(alloc)>::deallocate(-        alloc, base, size + align - 1 + sizeof(std::ptrdiff_t));-  }-}- #if !defined(GENERATING_DOCUMENTATION)  template <typename Service>@@ -103,15 +34,48 @@   return e.service_registry_->template use_service<Service>(); } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Service, typename... Args>-Service& make_service(execution_context& e, Args&&... args)+Service& make_service(execution_context& e, ASIO_MOVE_ARG(Args)... args) {-  // Check that Service meets the necessary type requirements.-  (void)static_cast<execution_context::service*>(static_cast<Service*>(0));+  detail::scoped_ptr<Service> svc(+      new Service(e, ASIO_MOVE_CAST(Args)(args)...));+  e.service_registry_->template add_service<Service>(svc.get());+  Service& result = *svc;+  svc.release();+  return result;+} -  return e.service_registry_->template make_service<Service>(-      static_cast<Args&&>(args)...);+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Service>+Service& make_service(execution_context& e)+{+  detail::scoped_ptr<Service> svc(new Service(e));+  e.service_registry_->template add_service<Service>(svc.get());+  Service& result = *svc;+  svc.release();+  return result; }++#define ASIO_PRIVATE_MAKE_SERVICE_DEF(n) \+  template <typename Service, ASIO_VARIADIC_TPARAMS(n)> \+  Service& make_service(execution_context& e, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    detail::scoped_ptr<Service> svc( \+        new Service(e, ASIO_VARIADIC_MOVE_ARGS(n))); \+    e.service_registry_->template add_service<Service>(svc.get()); \+    Service& result = *svc; \+    svc.release(); \+    return result; \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_MAKE_SERVICE_DEF)+#undef ASIO_PRIVATE_MAKE_SERVICE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)  template <typename Service> inline void add_service(execution_context& e, Service* svc)
link/modules/asio-standalone/asio/include/asio/impl/execution_context.ipp view
@@ -2,7 +2,7 @@ // impl/execution_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -24,44 +24,15 @@ namespace asio {  execution_context::execution_context()-  : execution_context(-      detail::allocate_object<allocator_impl<std::allocator<void>>>(-        std::allocator<void>(), std::allocator<void>()))-{-}--execution_context::execution_context(allocator_impl_base* alloc)-  : allocator_{alloc},-    service_registry_(-        detail::allocate_object<detail::service_registry>(-          allocator<void>(*this), *this))-{-}--execution_context::execution_context(-    const execution_context::service_maker& initial_services)-  : execution_context(-      detail::allocate_object<allocator_impl<std::allocator<void>>>(-        std::allocator<void>(), std::allocator<void>()),-      initial_services)+  : service_registry_(new asio::detail::service_registry(*this)) { } -execution_context::execution_context(allocator_impl_base* alloc,-    const execution_context::service_maker& initial_services)-  : allocator_{alloc},-    service_registry_(-        detail::allocate_object<detail::service_registry>(-          allocator<void>(*this), *this))-{-  initial_services.make(*this);-}- execution_context::~execution_context() {   shutdown();   destroy();-  detail::deallocate_object(allocator<void>(*this), service_registry_);+  delete service_registry_; }  void execution_context::shutdown()@@ -80,14 +51,9 @@   service_registry_->notify_fork(event); } -execution_context::allocator_impl_base::~allocator_impl_base()-{-}- execution_context::service::service(execution_context& owner)   : owner_(owner),-    next_(0),-    destroy_(0)+    next_(0) { } @@ -96,10 +62,6 @@ }  void execution_context::service::notify_fork(execution_context::fork_event)-{-}--execution_context::service_maker::~service_maker() { } 
link/modules/asio-standalone/asio/include/asio/impl/executor.hpp view
@@ -2,7 +2,7 @@ // impl/executor.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,7 +19,6 @@  #if !defined(ASIO_NO_TS_EXECUTORS) -#include <new> #include "asio/detail/atomic_count.hpp" #include "asio/detail/global.hpp" #include "asio/detail/memory.hpp"@@ -48,12 +47,7 @@     return p;   } -  static impl_base* create(std::nothrow_t, const Executor& e) noexcept-  {-    return new (std::nothrow) impl(e, std::allocator<void>());-  }--  impl(const Executor& e, const Allocator& a) noexcept+  impl(const Executor& e, const Allocator& a) ASIO_NOEXCEPT     : impl_base(false),       ref_count_(1),       executor_(e),@@ -61,13 +55,13 @@   {   } -  impl_base* clone() const noexcept+  impl_base* clone() const ASIO_NOEXCEPT   {     detail::ref_count_up(ref_count_);     return const_cast<impl_base*>(static_cast<const impl_base*>(this));   } -  void destroy() noexcept+  void destroy() ASIO_NOEXCEPT   {     if (detail::ref_count_down(ref_count_))     {@@ -78,52 +72,52 @@     }   } -  void on_work_started() noexcept+  void on_work_started() ASIO_NOEXCEPT   {     executor_.on_work_started();   } -  void on_work_finished() noexcept+  void on_work_finished() ASIO_NOEXCEPT   {     executor_.on_work_finished();   } -  execution_context& context() noexcept+  execution_context& context() ASIO_NOEXCEPT   {     return executor_.context();   } -  void dispatch(function&& f)+  void dispatch(ASIO_MOVE_ARG(function) f)   {-    executor_.dispatch(static_cast<function&&>(f), allocator_);+    executor_.dispatch(ASIO_MOVE_CAST(function)(f), allocator_);   } -  void post(function&& f)+  void post(ASIO_MOVE_ARG(function) f)   {-    executor_.post(static_cast<function&&>(f), allocator_);+    executor_.post(ASIO_MOVE_CAST(function)(f), allocator_);   } -  void defer(function&& f)+  void defer(ASIO_MOVE_ARG(function) f)   {-    executor_.defer(static_cast<function&&>(f), allocator_);+    executor_.defer(ASIO_MOVE_CAST(function)(f), allocator_);   } -  type_id_result_type target_type() const noexcept+  type_id_result_type target_type() const ASIO_NOEXCEPT   {     return type_id<Executor>();   } -  void* target() noexcept+  void* target() ASIO_NOEXCEPT   {     return &executor_;   } -  const void* target() const noexcept+  const void* target() const ASIO_NOEXCEPT   {     return &executor_;   } -  bool equals(const impl_base* e) const noexcept+  bool equals(const impl_base* e) const ASIO_NOEXCEPT   {     if (this == e)       return true;@@ -170,12 +164,7 @@   static impl_base* create(const system_executor&,       const Allocator& = Allocator())   {-    return &detail::global<impl<system_executor, std::allocator<void>> >();-  }--  static impl_base* create(std::nothrow_t, const system_executor&) noexcept-  {-    return &detail::global<impl<system_executor, std::allocator<void>> >();+    return &detail::global<impl<system_executor, std::allocator<void> > >();   }    impl()@@ -183,64 +172,64 @@   {   } -  impl_base* clone() const noexcept+  impl_base* clone() const ASIO_NOEXCEPT   {     return const_cast<impl_base*>(static_cast<const impl_base*>(this));   } -  void destroy() noexcept+  void destroy() ASIO_NOEXCEPT   {   } -  void on_work_started() noexcept+  void on_work_started() ASIO_NOEXCEPT   {     executor_.on_work_started();   } -  void on_work_finished() noexcept+  void on_work_finished() ASIO_NOEXCEPT   {     executor_.on_work_finished();   } -  execution_context& context() noexcept+  execution_context& context() ASIO_NOEXCEPT   {     return executor_.context();   } -  void dispatch(function&& f)+  void dispatch(ASIO_MOVE_ARG(function) f)   {-    executor_.dispatch(static_cast<function&&>(f),+    executor_.dispatch(ASIO_MOVE_CAST(function)(f),         std::allocator<void>());   } -  void post(function&& f)+  void post(ASIO_MOVE_ARG(function) f)   {-    executor_.post(static_cast<function&&>(f),+    executor_.post(ASIO_MOVE_CAST(function)(f),         std::allocator<void>());   } -  void defer(function&& f)+  void defer(ASIO_MOVE_ARG(function) f)   {-    executor_.defer(static_cast<function&&>(f),+    executor_.defer(ASIO_MOVE_CAST(function)(f),         std::allocator<void>());   } -  type_id_result_type target_type() const noexcept+  type_id_result_type target_type() const ASIO_NOEXCEPT   {     return type_id<system_executor>();   } -  void* target() noexcept+  void* target() ASIO_NOEXCEPT   {     return &executor_;   } -  const void* target() const noexcept+  const void* target() const ASIO_NOEXCEPT   {     return &executor_;   } -  bool equals(const impl_base* e) const noexcept+  bool equals(const impl_base* e) const ASIO_NOEXCEPT   {     return this == e;   }@@ -251,13 +240,7 @@  template <typename Executor> executor::executor(Executor e)-  : impl_(impl<Executor, std::allocator<void>>::create(e))-{-}--template <typename Executor>-executor::executor(std::nothrow_t, Executor e) noexcept-  : impl_(impl<Executor, std::allocator<void>>::create(std::nothrow, e))+  : impl_(impl<Executor, std::allocator<void> >::create(e)) { } @@ -268,39 +251,39 @@ }  template <typename Function, typename Allocator>-void executor::dispatch(Function&& f,+void executor::dispatch(ASIO_MOVE_ARG(Function) f,     const Allocator& a) const {   impl_base* i = get_impl();   if (i->fast_dispatch_)-    system_executor().dispatch(static_cast<Function&&>(f), a);+    system_executor().dispatch(ASIO_MOVE_CAST(Function)(f), a);   else-    i->dispatch(function(static_cast<Function&&>(f), a));+    i->dispatch(function(ASIO_MOVE_CAST(Function)(f), a)); }  template <typename Function, typename Allocator>-void executor::post(Function&& f,+void executor::post(ASIO_MOVE_ARG(Function) f,     const Allocator& a) const {-  get_impl()->post(function(static_cast<Function&&>(f), a));+  get_impl()->post(function(ASIO_MOVE_CAST(Function)(f), a)); }  template <typename Function, typename Allocator>-void executor::defer(Function&& f,+void executor::defer(ASIO_MOVE_ARG(Function) f,     const Allocator& a) const {-  get_impl()->defer(function(static_cast<Function&&>(f), a));+  get_impl()->defer(function(ASIO_MOVE_CAST(Function)(f), a)); }  template <typename Executor>-Executor* executor::target() noexcept+Executor* executor::target() ASIO_NOEXCEPT {   return impl_ && impl_->target_type() == type_id<Executor>()     ? static_cast<Executor*>(impl_->target()) : 0; }  template <typename Executor>-const Executor* executor::target() const noexcept+const Executor* executor::target() const ASIO_NOEXCEPT {   return impl_ && impl_->target_type() == type_id<Executor>()     ? static_cast<Executor*>(impl_->target()) : 0;
link/modules/asio-standalone/asio/include/asio/impl/executor.ipp view
@@ -2,7 +2,7 @@ // impl/executor.ipp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -25,11 +25,11 @@  namespace asio { -bad_executor::bad_executor() noexcept+bad_executor::bad_executor() ASIO_NOEXCEPT { } -const char* bad_executor::what() const noexcept+const char* bad_executor::what() const ASIO_NOEXCEPT_OR_NOTHROW {   return "bad executor"; }
+ link/modules/asio-standalone/asio/include/asio/impl/handler_alloc_hook.ipp view
@@ -0,0 +1,62 @@+//+// impl/handler_alloc_hook.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_IMPL_HANDLER_ALLOC_HOOK_IPP+#define ASIO_IMPL_HANDLER_ALLOC_HOOK_IPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/memory.hpp"+#include "asio/detail/thread_context.hpp"+#include "asio/detail/thread_info_base.hpp"+#include "asio/handler_alloc_hook.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size, ...)+{+#if defined(ASIO_NO_DEPRECATED)+  (void)size;+  return asio_handler_allocate_is_no_longer_used();+#elif !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+  return detail::thread_info_base::allocate(+      detail::thread_context::top_of_thread_call_stack(), size);+#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+  return aligned_new(ASIO_DEFAULT_ALIGN, size);+#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+}++asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size, ...)+{+#if defined(ASIO_NO_DEPRECATED)+  (void)pointer;+  (void)size;+  return asio_handler_deallocate_is_no_longer_used();+#elif !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+  detail::thread_info_base::deallocate(+      detail::thread_context::top_of_thread_call_stack(), pointer, size);+#else // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+  (void)size;+  aligned_delete(pointer);+#endif // !defined(ASIO_DISABLE_SMALL_BLOCK_RECYCLING)+}++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_IMPL_HANDLER_ALLOC_HOOK_IPP
link/modules/asio-standalone/asio/include/asio/impl/io_context.hpp view
@@ -2,7 +2,7 @@ // impl/io_context.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -15,7 +15,6 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include "asio/config.hpp" #include "asio/detail/completion_handler.hpp" #include "asio/detail/executor_op.hpp" #include "asio/detail/fenced_block.hpp"@@ -29,30 +28,6 @@  namespace asio { -template <typename Allocator>-io_context::io_context(allocator_arg_t, const Allocator& a)-  : execution_context(std::allocator_arg, a, config_from_concurrency_hint()),-    impl_(asio::make_service<impl_type>(*this, false))-{-}--template <typename Allocator>-io_context::io_context(allocator_arg_t,-    const Allocator& a, int concurrency_hint)-  : execution_context(std::allocator_arg, a,-      config_from_concurrency_hint(concurrency_hint)),-    impl_(asio::make_service<impl_type>(*this, false))-{-}--template <typename Allocator>-io_context::io_context(allocator_arg_t, const Allocator& a,-    const execution_context::service_maker& initial_services)-  : execution_context(std::allocator_arg, a, initial_services),-    impl_(asio::make_service<impl_type>(*this, false))-{-}- #if !defined(GENERATING_DOCUMENTATION)  template <typename Service>@@ -75,11 +50,13 @@ #endif // !defined(GENERATING_DOCUMENTATION)  inline io_context::executor_type-io_context::get_executor() noexcept+io_context::get_executor() ASIO_NOEXCEPT {   return executor_type(*this); } +#if defined(ASIO_HAS_CHRONO)+ template <typename Rep, typename Period> std::size_t io_context::run_for(     const chrono::duration<Rep, Period>& rel_time)@@ -131,8 +108,104 @@   return 0; } +#endif // defined(ASIO_HAS_CHRONO)+ #if !defined(ASIO_NO_DEPRECATED) +inline void io_context::reset()+{+  restart();+}++struct io_context::initiate_dispatch+{+  template <typename LegacyCompletionHandler>+  void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,+      io_context* self) const+  {+    // If you get an error on the following line it means that your handler does+    // not meet the documented type requirements for a LegacyCompletionHandler.+    ASIO_LEGACY_COMPLETION_HANDLER_CHECK(+        LegacyCompletionHandler, handler) type_check;++    detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);+    if (self->impl_.can_dispatch())+    {+      detail::fenced_block b(detail::fenced_block::full);+      asio_handler_invoke_helpers::invoke(+          handler2.value, handler2.value);+    }+    else+    {+      // Allocate and construct an operation to wrap the handler.+      typedef detail::completion_handler<+        typename decay<LegacyCompletionHandler>::type, executor_type> op;+      typename op::ptr p = { detail::addressof(handler2.value),+        op::ptr::allocate(handler2.value), 0 };+      p.p = new (p.v) op(handler2.value, self->get_executor());++      ASIO_HANDLER_CREATION((*self, *p.p,+            "io_context", self, 0, "dispatch"));++      self->impl_.do_dispatch(p.p);+      p.v = p.p = 0;+    }+  }+};++template <typename LegacyCompletionHandler>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+io_context::dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<LegacyCompletionHandler, void ()>(+        declval<initiate_dispatch>(), handler, this)))+{+  return async_initiate<LegacyCompletionHandler, void ()>(+      initiate_dispatch(), handler, this);+}++struct io_context::initiate_post+{+  template <typename LegacyCompletionHandler>+  void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,+      io_context* self) const+  {+    // If you get an error on the following line it means that your handler does+    // not meet the documented type requirements for a LegacyCompletionHandler.+    ASIO_LEGACY_COMPLETION_HANDLER_CHECK(+        LegacyCompletionHandler, handler) type_check;++    detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);++    bool is_continuation =+      asio_handler_cont_helpers::is_continuation(handler2.value);++    // Allocate and construct an operation to wrap the handler.+    typedef detail::completion_handler<+      typename decay<LegacyCompletionHandler>::type, executor_type> op;+    typename op::ptr p = { detail::addressof(handler2.value),+        op::ptr::allocate(handler2.value), 0 };+    p.p = new (p.v) op(handler2.value, self->get_executor());++    ASIO_HANDLER_CREATION((*self, *p.p,+          "io_context", self, 0, "post"));++    self->impl_.post_immediate_completion(p.p, is_continuation);+    p.v = p.p = 0;+  }+};++template <typename LegacyCompletionHandler>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+io_context::post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<LegacyCompletionHandler, void ()>(+        declval<initiate_post>(), handler, this)))+{+  return async_initiate<LegacyCompletionHandler, void ()>(+      initiate_post(), handler, this);+}+ template <typename Handler> #if defined(GENERATING_DOCUMENTATION) unspecified@@ -149,7 +222,7 @@ template <typename Allocator, uintptr_t Bits> io_context::basic_executor_type<Allocator, Bits>& io_context::basic_executor_type<Allocator, Bits>::operator=(-    const basic_executor_type& other) noexcept+    const basic_executor_type& other) ASIO_NOEXCEPT {   if (this != &other)   {@@ -167,10 +240,11 @@   return *this; } +#if defined(ASIO_HAS_MOVE) template <typename Allocator, uintptr_t Bits> io_context::basic_executor_type<Allocator, Bits>& io_context::basic_executor_type<Allocator, Bits>::operator=(-    basic_executor_type&& other) noexcept+    basic_executor_type&& other) ASIO_NOEXCEPT {   if (this != &other)   {@@ -186,10 +260,11 @@   }   return *this; }+#endif // defined(ASIO_HAS_MOVE)  template <typename Allocator, uintptr_t Bits> inline bool io_context::basic_executor_type<Allocator,-    Bits>::running_in_this_thread() const noexcept+    Bits>::running_in_this_thread() const ASIO_NOEXCEPT {   return context_ptr()->impl_.can_dispatch(); }@@ -197,32 +272,36 @@ template <typename Allocator, uintptr_t Bits> template <typename Function> void io_context::basic_executor_type<Allocator, Bits>::execute(-    Function&& f) const+    ASIO_MOVE_ARG(Function) f) const {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // Invoke immediately if the blocking.possibly property is enabled and we are   // already inside the thread pool.   if ((bits() & blocking_never) == 0 && context_ptr()->impl_.can_dispatch())   {     // Make a local, non-const copy of the function.-    function_type tmp(static_cast<Function&&>(f));+    function_type tmp(ASIO_MOVE_CAST(Function)(f)); -#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  && !defined(ASIO_NO_EXCEPTIONS)     try     {-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       //   && !defined(ASIO_NO_EXCEPTIONS)       detail::fenced_block b(detail::fenced_block::full);-      static_cast<function_type&&>(tmp)();+      asio_handler_invoke_helpers::invoke(tmp, tmp);       return;-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  && !defined(ASIO_NO_EXCEPTIONS)     }     catch (...)     {       context_ptr()->impl_.capture_current_exception();       return;     }-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       //   && !defined(ASIO_NO_EXCEPTIONS)   }    // Allocate and construct an operation to wrap the function.@@ -230,7 +309,7 @@   typename op::ptr p = {       detail::addressof(static_cast<const Allocator&>(*this)),       op::ptr::allocate(static_cast<const Allocator&>(*this)), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f),+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f),       static_cast<const Allocator&>(*this));    ASIO_HANDLER_CREATION((*context_ptr(), *p.p,@@ -244,21 +323,21 @@ #if !defined(ASIO_NO_TS_EXECUTORS) template <typename Allocator, uintptr_t Bits> inline io_context& io_context::basic_executor_type<-    Allocator, Bits>::context() const noexcept+    Allocator, Bits>::context() const ASIO_NOEXCEPT {   return *context_ptr(); }  template <typename Allocator, uintptr_t Bits> inline void io_context::basic_executor_type<Allocator,-    Bits>::on_work_started() const noexcept+    Bits>::on_work_started() const ASIO_NOEXCEPT {   context_ptr()->impl_.work_started(); }  template <typename Allocator, uintptr_t Bits> inline void io_context::basic_executor_type<Allocator,-    Bits>::on_work_finished() const noexcept+    Bits>::on_work_finished() const ASIO_NOEXCEPT {   context_ptr()->impl_.work_finished(); }@@ -266,18 +345,18 @@ template <typename Allocator, uintptr_t Bits> template <typename Function, typename OtherAllocator> void io_context::basic_executor_type<Allocator, Bits>::dispatch(-    Function&& f, const OtherAllocator& a) const+    ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // Invoke immediately if we are already inside the thread pool.   if (context_ptr()->impl_.can_dispatch())   {     // Make a local, non-const copy of the function.-    function_type tmp(static_cast<Function&&>(f));+    function_type tmp(ASIO_MOVE_CAST(Function)(f));      detail::fenced_block b(detail::fenced_block::full);-    static_cast<function_type&&>(tmp)();+    asio_handler_invoke_helpers::invoke(tmp, tmp);     return;   } @@ -285,7 +364,7 @@   typedef detail::executor_op<function_type,       OtherAllocator, detail::operation> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);    ASIO_HANDLER_CREATION((*context_ptr(), *p.p,         "io_context", context_ptr(), 0, "dispatch"));@@ -297,13 +376,15 @@ template <typename Allocator, uintptr_t Bits> template <typename Function, typename OtherAllocator> void io_context::basic_executor_type<Allocator, Bits>::post(-    Function&& f, const OtherAllocator& a) const+    ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {+  typedef typename decay<Function>::type function_type;+   // Allocate and construct an operation to wrap the function.-  typedef detail::executor_op<decay_t<Function>,+  typedef detail::executor_op<function_type,       OtherAllocator, detail::operation> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);    ASIO_HANDLER_CREATION((*context_ptr(), *p.p,         "io_context", context_ptr(), 0, "post"));@@ -315,13 +396,15 @@ template <typename Allocator, uintptr_t Bits> template <typename Function, typename OtherAllocator> void io_context::basic_executor_type<Allocator, Bits>::defer(-    Function&& f, const OtherAllocator& a) const+    ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {+  typedef typename decay<Function>::type function_type;+   // Allocate and construct an operation to wrap the function.-  typedef detail::executor_op<decay_t<Function>,+  typedef detail::executor_op<function_type,       OtherAllocator, detail::operation> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);    ASIO_HANDLER_CREATION((*context_ptr(), *p.p,         "io_context", context_ptr(), 0, "defer"));@@ -330,6 +413,30 @@   p.v = p.p = 0; } #endif // !defined(ASIO_NO_TS_EXECUTORS)++#if !defined(ASIO_NO_DEPRECATED)+inline io_context::work::work(asio::io_context& io_context)+  : io_context_impl_(io_context.impl_)+{+  io_context_impl_.work_started();+}++inline io_context::work::work(const work& other)+  : io_context_impl_(other.io_context_impl_)+{+  io_context_impl_.work_started();+}++inline io_context::work::~work()+{+  io_context_impl_.work_finished();+}++inline asio::io_context& io_context::work::get_io_context()+{+  return static_cast<asio::io_context&>(io_context_impl_.context());+}+#endif // !defined(ASIO_NO_DEPRECATED)  inline asio::io_context& io_context::service::get_io_context() {
link/modules/asio-standalone/asio/include/asio/impl/io_context.ipp view
@@ -2,7 +2,7 @@ // impl/io_context.ipp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,10 +16,10 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include "asio/config.hpp" #include "asio/io_context.hpp" #include "asio/detail/concurrency_hint.hpp" #include "asio/detail/limits.hpp"+#include "asio/detail/scoped_ptr.hpp" #include "asio/detail/service_registry.hpp" #include "asio/detail/throw_error.hpp" @@ -34,21 +34,22 @@ namespace asio {  io_context::io_context()-  : execution_context(config_from_concurrency_hint()),-    impl_(asio::make_service<impl_type>(*this, false))+  : impl_(add_impl(new impl_type(*this,+          ASIO_CONCURRENCY_HINT_DEFAULT, false))) { }  io_context::io_context(int concurrency_hint)-  : execution_context(config_from_concurrency_hint(concurrency_hint)),-    impl_(asio::make_service<impl_type>(*this, false))+  : impl_(add_impl(new impl_type(*this, concurrency_hint == 1+          ? ASIO_CONCURRENCY_HINT_1 : concurrency_hint, false))) { } -io_context::io_context(const execution_context::service_maker& initial_services)-  : execution_context(initial_services),-    impl_(asio::make_service<impl_type>(*this, false))+io_context::impl_type& io_context::add_impl(io_context::impl_type* impl) {+  asio::detail::scoped_ptr<impl_type> scoped_impl(impl);+  asio::add_service<impl_type>(*this, scoped_impl.get());+  return *scoped_impl.release(); }  io_context::~io_context()@@ -64,6 +65,13 @@   return s; } +#if !defined(ASIO_NO_DEPRECATED)+io_context::count_type io_context::run(asio::error_code& ec)+{+  return impl_.run(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ io_context::count_type io_context::run_one() {   asio::error_code ec;@@ -72,6 +80,13 @@   return s; } +#if !defined(ASIO_NO_DEPRECATED)+io_context::count_type io_context::run_one(asio::error_code& ec)+{+  return impl_.run_one(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ io_context::count_type io_context::poll() {   asio::error_code ec;@@ -80,6 +95,13 @@   return s; } +#if !defined(ASIO_NO_DEPRECATED)+io_context::count_type io_context::poll(asio::error_code& ec)+{+  return impl_.poll(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ io_context::count_type io_context::poll_one() {   asio::error_code ec;@@ -88,6 +110,13 @@   return s; } +#if !defined(ASIO_NO_DEPRECATED)+io_context::count_type io_context::poll_one(asio::error_code& ec)+{+  return impl_.poll_one(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ void io_context::stop() {   impl_.stop();@@ -114,11 +143,31 @@  void io_context::service::shutdown() {+#if !defined(ASIO_NO_DEPRECATED)+  shutdown_service();+#endif // !defined(ASIO_NO_DEPRECATED) } -void io_context::service::notify_fork(io_context::fork_event)+#if !defined(ASIO_NO_DEPRECATED)+void io_context::service::shutdown_service() { }+#endif // !defined(ASIO_NO_DEPRECATED)++void io_context::service::notify_fork(io_context::fork_event ev)+{+#if !defined(ASIO_NO_DEPRECATED)+  fork_service(ev);+#else // !defined(ASIO_NO_DEPRECATED)+  (void)ev;+#endif // !defined(ASIO_NO_DEPRECATED)+}++#if !defined(ASIO_NO_DEPRECATED)+void io_context::service::fork_service(io_context::fork_event)+{+}+#endif // !defined(ASIO_NO_DEPRECATED)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/impl/multiple_exceptions.ipp view
@@ -2,7 +2,7 @@ // impl/multiple_exceptions.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,13 +22,15 @@  namespace asio { +#if defined(ASIO_HAS_STD_EXCEPTION_PTR)+ multiple_exceptions::multiple_exceptions(-    std::exception_ptr first) noexcept-  : first_(static_cast<std::exception_ptr&&>(first))+    std::exception_ptr first) ASIO_NOEXCEPT+  : first_(ASIO_MOVE_CAST(std::exception_ptr)(first)) { } -const char* multiple_exceptions::what() const noexcept+const char* multiple_exceptions::what() const ASIO_NOEXCEPT_OR_NOTHROW {   return "multiple exceptions"; }@@ -37,6 +39,8 @@ {   return first_; }++#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/impl/prepend.hpp view
@@ -2,7 +2,7 @@ // impl/prepend.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,12 +16,15 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"+ #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp" @@ -36,26 +39,26 @@   typedef void result_type;    template <typename H>-  prepend_handler(H&& handler, std::tuple<Values...> values)-    : handler_(static_cast<H&&>(handler)),-      values_(static_cast<std::tuple<Values...>&&>(values))+  prepend_handler(ASIO_MOVE_ARG(H) handler, std::tuple<Values...> values)+    : handler_(ASIO_MOVE_CAST(H)(handler)),+      values_(ASIO_MOVE_CAST(std::tuple<Values...>)(values))   {   }    template <typename... Args>-  void operator()(Args&&... args)+  void operator()(ASIO_MOVE_ARG(Args)... args)   {     this->invoke(         index_sequence_for<Values...>{},-        static_cast<Args&&>(args)...);+        ASIO_MOVE_CAST(Args)(args)...);   }    template <std::size_t... I, typename... Args>-  void invoke(index_sequence<I...>, Args&&... args)+  void invoke(index_sequence<I...>, ASIO_MOVE_ARG(Args)... args)   {-    static_cast<Handler&&>(handler_)(-        static_cast<Values&&>(std::get<I>(values_))...,-        static_cast<Args&&>(args)...);+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        ASIO_MOVE_CAST(Values)(std::get<I>(values_))...,+        ASIO_MOVE_CAST(Args)(args)...);   }  //private:@@ -64,6 +67,32 @@ };  template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    prepend_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    prepend_handler<Handler>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation(     prepend_handler<Handler>* this_handler) {@@ -71,13 +100,37 @@         this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    prepend_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    prepend_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature, typename... Values> struct prepend_signature;  template <typename R, typename... Args, typename... Values> struct prepend_signature<R(Args...), Values...> {-  typedef R type(Values..., decay_t<Args>...);+  typedef R type(Values..., typename decay<Args>::type...); };  } // namespace detail@@ -95,49 +148,48 @@       Signature, Values...>::type signature;    template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>+  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;--    template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        std::tuple<Values...> values, Args&&... args) &&+    init_wrapper(Initiation init)+      : initiation_(ASIO_MOVE_CAST(Initiation)(init))     {-      static_cast<Initiation&&>(*this)(-          detail::prepend_handler<decay_t<Handler>, Values...>(-            static_cast<Handler&&>(handler),-            static_cast<std::tuple<Values...>&&>(values)),-          static_cast<Args&&>(args)...);     }      template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        std::tuple<Values...> values, Args&&... args) const &+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        std::tuple<Values...> values,+        ASIO_MOVE_ARG(Args)... args)     {-      static_cast<const Initiation&>(*this)(-          detail::prepend_handler<decay_t<Handler>, Values...>(-            static_cast<Handler&&>(handler),-            static_cast<std::tuple<Values...>&&>(values)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation_)(+          detail::prepend_handler<+            typename decay<Handler>::type, Values...>(+              ASIO_MOVE_CAST(Handler)(handler),+              ASIO_MOVE_CAST(std::tuple<Values...>)(values)),+          ASIO_MOVE_CAST(Args)(args)...);     }++    Initiation initiation_;   };    template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<CompletionToken, signature>(-        declval<init_wrapper<decay_t<Initiation>>>(),-        token.token_,-        static_cast<std::tuple<Values...>&&>(token.values_),-        static_cast<Args&&>(args)...))+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature,+      (async_initiate<CompletionToken, signature>(+        declval<init_wrapper<typename decay<Initiation>::type> >(),+        declval<CompletionToken&>(),+        declval<std::tuple<Values...> >(),+        declval<ASIO_MOVE_ARG(Args)>()...)))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)   {     return async_initiate<CompletionToken, signature>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),+        init_wrapper<typename decay<Initiation>::type>(+          ASIO_MOVE_CAST(Initiation)(initiation)),         token.token_,-        static_cast<std::tuple<Values...>&&>(token.values_),-        static_cast<Args&&>(args)...);+        ASIO_MOVE_CAST(std::tuple<Values...>)(token.values_),+        ASIO_MOVE_CAST(Args)(args)...);   } }; @@ -147,15 +199,18 @@     detail::prepend_handler<Handler, Values...>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::prepend_handler<Handler, Values...>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::prepend_handler<Handler, Values...>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::prepend_handler<Handler, Values...>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::prepend_handler<Handler, Values...>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }
link/modules/asio-standalone/asio/include/asio/impl/read.hpp view
@@ -2,7 +2,7 @@ // impl/read.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -24,7 +24,9 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -62,23 +64,20 @@     typename CompletionCondition> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    >::type) {   return detail::read_buffer_seq(s, buffers,       asio::buffer_sequence_begin(buffers),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); }  template <typename SyncReadStream, typename MutableBufferSequence> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,-    constraint_t<+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    >)+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);@@ -89,9 +88,9 @@ template <typename SyncReadStream, typename MutableBufferSequence> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,     asio::error_code& ec,-    constraint_t<+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    >)+    >::type) {   return read(s, buffers, transfer_all(), ec); }@@ -100,16 +99,13 @@     typename CompletionCondition> inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,     CompletionCondition completion_condition,-    constraint_t<+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = read(s, buffers,-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "read");   return bytes_transferred; }@@ -119,20 +115,17 @@ template <typename SyncReadStream, typename DynamicBuffer_v1,     typename CompletionCondition> std::size_t read(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type) {-  decay_t<DynamicBuffer_v1> b(-      static_cast<DynamicBuffer_v1&&>(buffers));+  typename decay<DynamicBuffer_v1>::type b(+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));    ec = asio::error_code();   std::size_t total_transferred = 0;@@ -157,55 +150,52 @@  template <typename SyncReadStream, typename DynamicBuffer_v1> inline std::size_t read(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = read(s,-      static_cast<DynamicBuffer_v1&&>(buffers), transfer_all(), ec);+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec);   asio::detail::throw_error(ec, "read");   return bytes_transferred; }  template <typename SyncReadStream, typename DynamicBuffer_v1> inline std::size_t read(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type) {-  return read(s, static_cast<DynamicBuffer_v1&&>(buffers),+  return read(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),       transfer_all(), ec); }  template <typename SyncReadStream, typename DynamicBuffer_v1,     typename CompletionCondition> inline std::size_t read(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = read(s,-      static_cast<DynamicBuffer_v1&&>(buffers),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "read");   return bytes_transferred; }@@ -217,13 +207,10 @@     typename CompletionCondition> inline std::size_t read(SyncReadStream& s,     asio::basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition, asio::error_code& ec) {   return read(s, basic_streambuf_ref<Allocator>(b),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); }  template <typename SyncReadStream, typename Allocator>@@ -245,13 +232,10 @@     typename CompletionCondition> inline std::size_t read(SyncReadStream& s,     asio::basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition) {   return read(s, basic_streambuf_ref<Allocator>(b),-      static_cast<CompletionCondition&&>(completion_condition));+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); }  #endif // !defined(ASIO_NO_IOSTREAM)@@ -262,12 +246,9 @@     typename CompletionCondition> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    >::type) {   DynamicBuffer_v2& b = buffers; @@ -297,13 +278,13 @@  template <typename SyncReadStream, typename DynamicBuffer_v2> inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = read(s,-      static_cast<DynamicBuffer_v2&&>(buffers), transfer_all(), ec);+      ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec);   asio::detail::throw_error(ec, "read");   return bytes_transferred; }@@ -311,11 +292,11 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,     asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)+    >::type) {-  return read(s, static_cast<DynamicBuffer_v2&&>(buffers),+  return read(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),       transfer_all(), ec); } @@ -323,17 +304,14 @@     typename CompletionCondition> inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = read(s,-      static_cast<DynamicBuffer_v2&&>(buffers),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "read");   return bytes_transferred; }@@ -356,10 +334,11 @@         stream_(stream),         buffers_(buffers),         start_(0),-        handler_(static_cast<ReadHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     read_op(const read_op& other)       : base_from_cancellation_state<ReadHandler>(other),         base_from_completion_cond<CompletionCondition>(other),@@ -372,15 +351,18 @@      read_op(read_op&& other)       : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),         base_from_completion_cond<CompletionCondition>(-          static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+          ASIO_MOVE_CAST(base_from_completion_cond<+            CompletionCondition>)(other)),         stream_(other.stream_),-        buffers_(static_cast<buffers_type&&>(other.buffers_)),+        buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)),         start_(other.start_),-        handler_(static_cast<ReadHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(asio::error_code ec,         std::size_t bytes_transferred, int start = 0)@@ -395,7 +377,7 @@           {             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read"));             stream_.async_read_some(buffers_.prepare(max_size),-                static_cast<read_op&&>(*this));+                ASIO_MOVE_CAST(read_op)(*this));           }           return; default:           buffers_.consume(bytes_transferred);@@ -411,7 +393,7 @@           }         } -        static_cast<ReadHandler&&>(handler_)(+        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(             static_cast<const asio::error_code&>(ec),             static_cast<const std::size_t&>(buffers_.total_consumed()));       }@@ -430,6 +412,38 @@   template <typename AsyncReadStream, typename MutableBufferSequence,       typename MutableBufferIterator, typename CompletionCondition,       typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,+        CompletionCondition, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename MutableBufferSequence,+      typename MutableBufferIterator, typename CompletionCondition,+      typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename MutableBufferSequence,+      typename MutableBufferIterator, typename CompletionCondition,+      typename ReadHandler>   inline bool asio_handler_is_continuation(       read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,         CompletionCondition, ReadHandler>* this_handler)@@ -439,6 +453,36 @@           this_handler->handler_);   } +  template <typename Function, typename AsyncReadStream,+      typename MutableBufferSequence, typename MutableBufferIterator,+      typename CompletionCondition, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename MutableBufferSequence, typename MutableBufferIterator,+      typename CompletionCondition, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_op<AsyncReadStream, MutableBufferSequence, MutableBufferIterator,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncReadStream, typename MutableBufferSequence,       typename MutableBufferIterator, typename CompletionCondition,       typename ReadHandler>@@ -463,16 +507,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return stream_.get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence,         typename CompletionCondition>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers,-        CompletionCondition&& completion_cond) const+        ASIO_MOVE_ARG(CompletionCondition) completion_cond) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a ReadHandler.@@ -502,18 +546,21 @@     DefaultCandidate>   : Associator<ReadHandler, DefaultCandidate> {-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_op<AsyncReadStream, MutableBufferSequence,-        MutableBufferIterator, CompletionCondition, ReadHandler>& h) noexcept+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_op<AsyncReadStream, MutableBufferSequence,+        MutableBufferIterator, CompletionCondition, ReadHandler>& h)+    ASIO_NOEXCEPT   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::read_op<AsyncReadStream, MutableBufferSequence,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_op<AsyncReadStream, MutableBufferSequence,         MutableBufferIterator, CompletionCondition, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -521,6 +568,54 @@  #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncReadStream,+    typename MutableBufferSequence, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_mutable_buffer_sequence<MutableBufferSequence>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read<AsyncReadStream> >(),+        token, buffers,+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read<AsyncReadStream>(s),+      token, buffers,+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncReadStream, typename MutableBufferSequence,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,+    ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_mutable_buffer_sequence<MutableBufferSequence>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read<AsyncReadStream> >(),+        token, buffers, transfer_all())))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read<AsyncReadStream>(s),+      token, buffers, transfer_all());+}+ #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)  namespace detail@@ -534,19 +629,20 @@   public:     template <typename BufferSequence>     read_dynbuf_v1_op(AsyncReadStream& stream,-        BufferSequence&& buffers,+        ASIO_MOVE_ARG(BufferSequence) buffers,         CompletionCondition& completion_condition, ReadHandler& handler)       : base_from_cancellation_state<ReadHandler>(           handler, enable_partial_cancellation()),         base_from_completion_cond<CompletionCondition>(completion_condition),         stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),         start_(0),         total_transferred_(0),-        handler_(static_cast<ReadHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     read_dynbuf_v1_op(const read_dynbuf_v1_op& other)       : base_from_cancellation_state<ReadHandler>(other),         base_from_completion_cond<CompletionCondition>(other),@@ -560,16 +656,19 @@      read_dynbuf_v1_op(read_dynbuf_v1_op&& other)       : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),         base_from_completion_cond<CompletionCondition>(-          static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+          ASIO_MOVE_CAST(base_from_completion_cond<+            CompletionCondition>)(other)),         stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),         start_(other.start_),         total_transferred_(other.total_transferred_),-        handler_(static_cast<ReadHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(asio::error_code ec,         std::size_t bytes_transferred, int start = 0)@@ -589,7 +688,7 @@           {             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read"));             stream_.async_read_some(buffers_.prepare(bytes_available),-                static_cast<read_dynbuf_v1_op&&>(*this));+                ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this));           }           return; default:           total_transferred_ += bytes_transferred;@@ -609,7 +708,7 @@           }         } -        static_cast<ReadHandler&&>(handler_)(+        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(             static_cast<const asio::error_code&>(ec),             static_cast<const std::size_t&>(total_transferred_));       }@@ -625,6 +724,36 @@    template <typename AsyncReadStream, typename DynamicBuffer_v1,       typename CompletionCondition, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+        CompletionCondition, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename CompletionCondition, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename CompletionCondition, typename ReadHandler>   inline bool asio_handler_is_continuation(       read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,         CompletionCondition, ReadHandler>* this_handler)@@ -634,6 +763,36 @@           this_handler->handler_);   } +  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename CompletionCondition,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename CompletionCondition,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncReadStream>   class initiate_async_read_dynbuf_v1   {@@ -645,16 +804,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return stream_.get_executor();     }      template <typename ReadHandler, typename DynamicBuffer_v1,         typename CompletionCondition>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v1&& buffers,-        CompletionCondition&& completion_cond) const+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+        ASIO_MOVE_ARG(CompletionCondition) completion_cond) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a ReadHandler.@@ -662,9 +821,9 @@        non_const_lvalue<ReadHandler> handler2(handler);       non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);-      read_dynbuf_v1_op<AsyncReadStream, decay_t<DynamicBuffer_v1>,-        CompletionCondition, decay_t<ReadHandler>>(-          stream_, static_cast<DynamicBuffer_v1&&>(buffers),+      read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type,+        CompletionCondition, typename decay<ReadHandler>::type>(+          stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),             completion_cond2.value, handler2.value)(               asio::error_code(), 0, 1);     }@@ -686,18 +845,20 @@     DefaultCandidate>   : Associator<ReadHandler, DefaultCandidate> {-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,-        CompletionCondition, ReadHandler>& h) noexcept+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,+        CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::read_dynbuf_v1_op<AsyncReadStream,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_dynbuf_v1_op<AsyncReadStream,         DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -705,6 +866,103 @@  #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncReadStream, typename DynamicBuffer_v1,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        transfer_all())))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+      transfer_all());+}++template <typename AsyncReadStream,+    typename DynamicBuffer_v1, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++#if !defined(ASIO_NO_EXTENSIONS)+#if !defined(ASIO_NO_IOSTREAM)++template <typename AsyncReadStream, typename Allocator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,+    ASIO_MOVE_ARG(ReadToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read(s, basic_streambuf_ref<Allocator>(b),+        ASIO_MOVE_CAST(ReadToken)(token))))+{+  return async_read(s, basic_streambuf_ref<Allocator>(b),+      ASIO_MOVE_CAST(ReadToken)(token));+}++template <typename AsyncReadStream,+    typename Allocator, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(ReadToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read(s, basic_streambuf_ref<Allocator>(b),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+        ASIO_MOVE_CAST(ReadToken)(token))))+{+  return async_read(s, basic_streambuf_ref<Allocator>(b),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+      ASIO_MOVE_CAST(ReadToken)(token));+}++#endif // !defined(ASIO_NO_IOSTREAM)+#endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)  namespace detail@@ -718,20 +976,21 @@   public:     template <typename BufferSequence>     read_dynbuf_v2_op(AsyncReadStream& stream,-        BufferSequence&& buffers,+        ASIO_MOVE_ARG(BufferSequence) buffers,         CompletionCondition& completion_condition, ReadHandler& handler)       : base_from_cancellation_state<ReadHandler>(           handler, enable_partial_cancellation()),         base_from_completion_cond<CompletionCondition>(completion_condition),         stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),         start_(0),         total_transferred_(0),         bytes_available_(0),-        handler_(static_cast<ReadHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     read_dynbuf_v2_op(const read_dynbuf_v2_op& other)       : base_from_cancellation_state<ReadHandler>(other),         base_from_completion_cond<CompletionCondition>(other),@@ -746,17 +1005,20 @@      read_dynbuf_v2_op(read_dynbuf_v2_op&& other)       : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),         base_from_completion_cond<CompletionCondition>(-          static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+          ASIO_MOVE_CAST(base_from_completion_cond<+            CompletionCondition>)(other)),         stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),         start_(other.start_),         total_transferred_(other.total_transferred_),         bytes_available_(other.bytes_available_),-        handler_(static_cast<ReadHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(asio::error_code ec,         std::size_t bytes_transferred, int start = 0)@@ -778,7 +1040,7 @@           {             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read"));             stream_.async_read_some(buffers_.data(pos, bytes_available_),-                static_cast<read_dynbuf_v2_op&&>(*this));+                ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this));           }           return; default:           total_transferred_ += bytes_transferred;@@ -798,7 +1060,7 @@           }         } -        static_cast<ReadHandler&&>(handler_)(+        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(             static_cast<const asio::error_code&>(ec),             static_cast<const std::size_t&>(total_transferred_));       }@@ -815,6 +1077,36 @@    template <typename AsyncReadStream, typename DynamicBuffer_v2,       typename CompletionCondition, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+        CompletionCondition, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename CompletionCondition, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename CompletionCondition, typename ReadHandler>   inline bool asio_handler_is_continuation(       read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,         CompletionCondition, ReadHandler>* this_handler)@@ -824,6 +1116,36 @@           this_handler->handler_);   } +  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename CompletionCondition,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename CompletionCondition,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncReadStream>   class initiate_async_read_dynbuf_v2   {@@ -835,16 +1157,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return stream_.get_executor();     }      template <typename ReadHandler, typename DynamicBuffer_v2,         typename CompletionCondition>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v2&& buffers,-        CompletionCondition&& completion_cond) const+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+        ASIO_MOVE_ARG(CompletionCondition) completion_cond) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a ReadHandler.@@ -852,9 +1174,9 @@        non_const_lvalue<ReadHandler> handler2(handler);       non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);-      read_dynbuf_v2_op<AsyncReadStream, decay_t<DynamicBuffer_v2>,-        CompletionCondition, decay_t<ReadHandler>>(-          stream_, static_cast<DynamicBuffer_v2&&>(buffers),+      read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type,+        CompletionCondition, typename decay<ReadHandler>::type>(+          stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),             completion_cond2.value, handler2.value)(               asio::error_code(), 0, 1);     }@@ -876,24 +1198,76 @@     DefaultCandidate>   : Associator<ReadHandler, DefaultCandidate> {-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,-        CompletionCondition, ReadHandler>& h) noexcept+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,+        CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::read_dynbuf_v2_op<AsyncReadStream,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_dynbuf_v2_op<AsyncReadStream,         DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);   } };  #endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v2,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,+    ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        transfer_all())))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+      transfer_all());+}++template <typename AsyncReadStream,+    typename DynamicBuffer_v2, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/impl/read_at.hpp view
@@ -2,7 +2,7 @@ // impl/read_at.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -24,7 +24,9 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -66,14 +68,11 @@     typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d,     uint64_t offset, const MutableBufferSequence& buffers,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition, asio::error_code& ec) {   return detail::read_at_buffer_sequence(d, offset, buffers,       asio::buffer_sequence_begin(buffers),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); }  template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>@@ -99,14 +98,11 @@     typename CompletionCondition> inline std::size_t read_at(SyncRandomAccessReadDevice& d,     uint64_t offset, const MutableBufferSequence& buffers,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition) {   asio::error_code ec;   std::size_t bytes_transferred = read_at(d, offset, buffers,-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "read_at");   return bytes_transferred; }@@ -118,10 +114,7 @@     typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d,     uint64_t offset, asio::basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition, asio::error_code& ec) {   ec = asio::error_code();   std::size_t total_transferred = 0;@@ -164,14 +157,11 @@     typename CompletionCondition> inline std::size_t read_at(SyncRandomAccessReadDevice& d,     uint64_t offset, asio::basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition) {   asio::error_code ec;   std::size_t bytes_transferred = read_at(d, offset, b,-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "read_at");   return bytes_transferred; }@@ -199,10 +189,11 @@         offset_(offset),         buffers_(buffers),         start_(0),-        handler_(static_cast<ReadHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     read_at_op(const read_at_op& other)       : base_from_cancellation_state<ReadHandler>(other),         base_from_completion_cond<CompletionCondition>(other),@@ -216,16 +207,19 @@      read_at_op(read_at_op&& other)       : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),         base_from_completion_cond<CompletionCondition>(-          static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+          ASIO_MOVE_CAST(base_from_completion_cond<+            CompletionCondition>)(other)),         device_(other.device_),         offset_(other.offset_),-        buffers_(static_cast<buffers_type&&>(other.buffers_)),+        buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)),         start_(other.start_),-        handler_(static_cast<ReadHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(asio::error_code ec,         std::size_t bytes_transferred, int start = 0)@@ -241,7 +235,7 @@             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at"));             device_.async_read_some_at(                 offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),-                static_cast<read_at_op&&>(*this));+                ASIO_MOVE_CAST(read_at_op)(*this));           }           return; default:           buffers_.consume(bytes_transferred);@@ -257,7 +251,7 @@           }         } -        static_cast<ReadHandler&&>(handler_)(+        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(             static_cast<const asio::error_code&>(ec),             static_cast<const std::size_t&>(buffers_.total_consumed()));       }@@ -277,6 +271,38 @@   template <typename AsyncRandomAccessReadDevice,       typename MutableBufferSequence, typename MutableBufferIterator,       typename CompletionCondition, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,+        MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncRandomAccessReadDevice,+      typename MutableBufferSequence, typename MutableBufferIterator,+      typename CompletionCondition, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,+        MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncRandomAccessReadDevice,+      typename MutableBufferSequence, typename MutableBufferIterator,+      typename CompletionCondition, typename ReadHandler>   inline bool asio_handler_is_continuation(       read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,         MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)@@ -286,6 +312,36 @@           this_handler->handler_);   } +  template <typename Function, typename AsyncRandomAccessReadDevice,+      typename MutableBufferSequence, typename MutableBufferIterator,+      typename CompletionCondition, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,+        MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncRandomAccessReadDevice,+      typename MutableBufferSequence, typename MutableBufferIterator,+      typename CompletionCondition, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,+        MutableBufferIterator, CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncRandomAccessReadDevice,       typename MutableBufferSequence, typename MutableBufferIterator,       typename CompletionCondition, typename ReadHandler>@@ -311,16 +367,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return device_.get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence,         typename CompletionCondition>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         uint64_t offset, const MutableBufferSequence& buffers,-        CompletionCondition&& completion_cond) const+        ASIO_MOVE_ARG(CompletionCondition) completion_cond) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a ReadHandler.@@ -350,20 +406,22 @@     DefaultCandidate>   : Associator<ReadHandler, DefaultCandidate> {-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_at_op<AsyncRandomAccessReadDevice,+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_at_op<AsyncRandomAccessReadDevice,         MutableBufferSequence, MutableBufferIterator,-        CompletionCondition, ReadHandler>& h) noexcept+        CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::read_at_op<AsyncRandomAccessReadDevice,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_at_op<AsyncRandomAccessReadDevice,         MutableBufferSequence, MutableBufferIterator,         CompletionCondition, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -371,6 +429,50 @@  #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncRandomAccessReadDevice,+    typename MutableBufferSequence, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+    uint64_t offset, const MutableBufferSequence& buffers,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(ReadToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),+        token, offset, buffers,+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),+      token, offset, buffers,+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+    uint64_t offset, const MutableBufferSequence& buffers,+    ASIO_MOVE_ARG(ReadToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),+        token, offset, buffers, transfer_all())))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),+      token, offset, buffers, transfer_all());+}+ #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) @@ -394,10 +496,11 @@         streambuf_(streambuf),         start_(0),         total_transferred_(0),-        handler_(static_cast<ReadHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     read_at_streambuf_op(const read_at_streambuf_op& other)       : base_from_cancellation_state<ReadHandler>(other),         base_from_completion_cond<CompletionCondition>(other),@@ -412,17 +515,20 @@      read_at_streambuf_op(read_at_streambuf_op&& other)       : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),         base_from_completion_cond<CompletionCondition>(-          static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+          ASIO_MOVE_CAST(base_from_completion_cond<+            CompletionCondition>)(other)),         device_(other.device_),         offset_(other.offset_),         streambuf_(other.streambuf_),         start_(other.start_),         total_transferred_(other.total_transferred_),-        handler_(static_cast<ReadHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(asio::error_code ec,         std::size_t bytes_transferred, int start = 0)@@ -439,7 +545,7 @@             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_read_at"));             device_.async_read_some_at(offset_ + total_transferred_,                 streambuf_.prepare(bytes_available),-                static_cast<read_at_streambuf_op&&>(*this));+                ASIO_MOVE_CAST(read_at_streambuf_op)(*this));           }           return; default:           total_transferred_ += bytes_transferred;@@ -455,7 +561,7 @@           }         } -        static_cast<ReadHandler&&>(handler_)(+        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(             static_cast<const asio::error_code&>(ec),             static_cast<const std::size_t&>(total_transferred_));       }@@ -472,6 +578,36 @@    template <typename AsyncRandomAccessReadDevice, typename Allocator,       typename CompletionCondition, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,+        CompletionCondition, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncRandomAccessReadDevice, typename Allocator,+      typename CompletionCondition, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncRandomAccessReadDevice, typename Allocator,+      typename CompletionCondition, typename ReadHandler>   inline bool asio_handler_is_continuation(       read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,         CompletionCondition, ReadHandler>* this_handler)@@ -481,6 +617,34 @@           this_handler->handler_);   } +  template <typename Function, typename AsyncRandomAccessReadDevice,+      typename Allocator, typename CompletionCondition, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncRandomAccessReadDevice,+      typename Allocator, typename CompletionCondition, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,+        CompletionCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncRandomAccessReadDevice>   class initiate_async_read_at_streambuf   {@@ -493,16 +657,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return device_.get_executor();     }      template <typename ReadHandler,         typename Allocator, typename CompletionCondition>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         uint64_t offset, basic_streambuf<Allocator>* b,-        CompletionCondition&& completion_cond) const+        ASIO_MOVE_ARG(CompletionCondition) completion_cond) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a ReadHandler.@@ -511,7 +675,7 @@       non_const_lvalue<ReadHandler> handler2(handler);       non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);       read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,-        CompletionCondition, decay_t<ReadHandler>>(+        CompletionCondition, typename decay<ReadHandler>::type>(           device_, offset, *b, completion_cond2.value, handler2.value)(             asio::error_code(), 0, 1);     }@@ -533,24 +697,72 @@     DefaultCandidate>   : Associator<ReadHandler, DefaultCandidate> {-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,-        Executor, CompletionCondition, ReadHandler>& h) noexcept+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,+        Executor, CompletionCondition, ReadHandler>& h) ASIO_NOEXCEPT   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,         Executor, CompletionCondition, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);   } };  #endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncRandomAccessReadDevice,+    typename Allocator, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+    uint64_t offset, asio::basic_streambuf<Allocator>& b,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(ReadToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_at_streambuf<+          AsyncRandomAccessReadDevice> >(),+        token, offset, &b,+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),+      token, offset, &b,+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncRandomAccessReadDevice, typename Allocator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+    uint64_t offset, asio::basic_streambuf<Allocator>& b,+    ASIO_MOVE_ARG(ReadToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_at_streambuf<+          AsyncRandomAccessReadDevice> >(),+        token, offset, &b, transfer_all())))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),+      token, offset, &b, transfer_all());+}  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/impl/read_until.hpp view
@@ -2,2662 +2,3449 @@ // impl/read_until.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ASIO_IMPL_READ_UNTIL_HPP-#define ASIO_IMPL_READ_UNTIL_HPP--#if defined(_MSC_VER) && (_MSC_VER >= 1200)-# pragma once-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)--#include <algorithm>-#include <string>-#include <vector>-#include <utility>-#include "asio/associator.hpp"-#include "asio/buffer.hpp"-#include "asio/buffers_iterator.hpp"-#include "asio/detail/base_from_cancellation_state.hpp"-#include "asio/detail/bind_handler.hpp"-#include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/handler_tracking.hpp"-#include "asio/detail/handler_type_requirements.hpp"-#include "asio/detail/limits.hpp"-#include "asio/detail/non_const_lvalue.hpp"-#include "asio/detail/throw_error.hpp"--#include "asio/detail/push_options.hpp"--namespace asio {--namespace detail-{-  // Algorithm that finds a subsequence of equal values in a sequence. Returns-  // (iterator,true) if a full match was found, in which case the iterator-  // points to the beginning of the match. Returns (iterator,false) if a-  // partial match was found at the end of the first sequence, in which case-  // the iterator points to the beginning of the partial match. Returns-  // (last1,false) if no full or partial match was found.-  template <typename Iterator1, typename Iterator2>-  std::pair<Iterator1, bool> partial_search(-      Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)-  {-    for (Iterator1 iter1 = first1; iter1 != last1; ++iter1)-    {-      Iterator1 test_iter1 = iter1;-      Iterator2 test_iter2 = first2;-      for (;; ++test_iter1, ++test_iter2)-      {-        if (test_iter2 == last2)-          return std::make_pair(iter1, true);-        if (test_iter1 == last1)-        {-          if (test_iter2 != first2)-            return std::make_pair(iter1, false);-          else-            break;-        }-        if (*test_iter1 != *test_iter2)-          break;-      }-    }-    return std::make_pair(last1, false);-  }--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)-  struct regex_match_flags-  {-    template <typename T>-    operator T() const-    {-      return T::match_default | T::match_partial;-    }-  };-#endif // !defined(ASIO_NO_EXTENSIONS)-#endif // defined(ASIO_HAS_BOOST_REGEX)-} // namespace detail--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--template <typename SyncReadStream, typename DynamicBuffer_v1>-inline std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers, char delim,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)-{-  asio::error_code ec;-  std::size_t bytes_transferred = read_until(s,-      static_cast<DynamicBuffer_v1&&>(buffers), delim, ec);-  asio::detail::throw_error(ec, "read_until");-  return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v1>-std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,-    char delim, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)-{-  decay_t<DynamicBuffer_v1> b(-      static_cast<DynamicBuffer_v1&&>(buffers));--  std::size_t search_position = 0;-  for (;;)-  {-    // Determine the range of the data to be searched.-    typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;-    typedef buffers_iterator<buffers_type> iterator;-    buffers_type data_buffers = b.data();-    iterator begin = iterator::begin(data_buffers);-    iterator start_pos = begin + search_position;-    iterator end = iterator::end(data_buffers);--    // Look for a match.-    iterator iter = std::find(start_pos, end, delim);-    if (iter != end)-    {-      // Found a match. We're done.-      ec = asio::error_code();-      return iter - begin + 1;-    }-    else-    {-      // No match. Next search can start with the new data.-      search_position = end - begin;-    }--    // Check if buffer is full.-    if (b.size() == b.max_size())-    {-      ec = error::not_found;-      return 0;-    }--    // Need more data.-    std::size_t bytes_to_read = std::min<std::size_t>(-          std::max<std::size_t>(512, b.capacity() - b.size()),-          std::min<std::size_t>(65536, b.max_size() - b.size()));-    b.commit(s.read_some(b.prepare(bytes_to_read), ec));-    if (ec)-      return 0;-  }-}--template <typename SyncReadStream, typename DynamicBuffer_v1>-inline std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,-    ASIO_STRING_VIEW_PARAM delim,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)-{-  asio::error_code ec;-  std::size_t bytes_transferred = read_until(s,-      static_cast<DynamicBuffer_v1&&>(buffers), delim, ec);-  asio::detail::throw_error(ec, "read_until");-  return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v1>-std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,-    ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)-{-  decay_t<DynamicBuffer_v1> b(-      static_cast<DynamicBuffer_v1&&>(buffers));--  std::size_t search_position = 0;-  for (;;)-  {-    // Determine the range of the data to be searched.-    typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;-    typedef buffers_iterator<buffers_type> iterator;-    buffers_type data_buffers = b.data();-    iterator begin = iterator::begin(data_buffers);-    iterator start_pos = begin + search_position;-    iterator end = iterator::end(data_buffers);--    // Look for a match.-    std::pair<iterator, bool> result = detail::partial_search(-        start_pos, end, delim.begin(), delim.end());-    if (result.first != end)-    {-      if (result.second)-      {-        // Full match. We're done.-        ec = asio::error_code();-        return result.first - begin + delim.length();-      }-      else-      {-        // Partial match. Next search needs to start from beginning of match.-        search_position = result.first - begin;-      }-    }-    else-    {-      // No match. Next search can start with the new data.-      search_position = end - begin;-    }--    // Check if buffer is full.-    if (b.size() == b.max_size())-    {-      ec = error::not_found;-      return 0;-    }--    // Need more data.-    std::size_t bytes_to_read = std::min<std::size_t>(-          std::max<std::size_t>(512, b.capacity() - b.size()),-          std::min<std::size_t>(65536, b.max_size() - b.size()));-    b.commit(s.read_some(b.prepare(bytes_to_read), ec));-    if (ec)-      return 0;-  }-}--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>-inline std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,-    const boost::basic_regex<char, Traits>& expr,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)-{-  asio::error_code ec;-  std::size_t bytes_transferred = read_until(s,-      static_cast<DynamicBuffer_v1&&>(buffers), expr, ec);-  asio::detail::throw_error(ec, "read_until");-  return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,-    const boost::basic_regex<char, Traits>& expr, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)-{-  decay_t<DynamicBuffer_v1> b(-      static_cast<DynamicBuffer_v1&&>(buffers));--  std::size_t search_position = 0;-  for (;;)-  {-    // Determine the range of the data to be searched.-    typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;-    typedef buffers_iterator<buffers_type> iterator;-    buffers_type data_buffers = b.data();-    iterator begin = iterator::begin(data_buffers);-    iterator start_pos = begin + search_position;-    iterator end = iterator::end(data_buffers);--    // Look for a match.-    boost::match_results<iterator,-      typename std::vector<boost::sub_match<iterator>>::allocator_type>-        match_results;-    if (regex_search(start_pos, end, match_results,-          expr, detail::regex_match_flags()))-    {-      if (match_results[0].matched)-      {-        // Full match. We're done.-        ec = asio::error_code();-        return match_results[0].second - begin;-      }-      else-      {-        // Partial match. Next search needs to start from beginning of match.-        search_position = match_results[0].first - begin;-      }-    }-    else-    {-      // No match. Next search can start with the new data.-      search_position = end - begin;-    }--    // Check if buffer is full.-    if (b.size() == b.max_size())-    {-      ec = error::not_found;-      return 0;-    }--    // Need more data.-    std::size_t bytes_to_read = std::min<std::size_t>(-          std::max<std::size_t>(512, b.capacity() - b.size()),-          std::min<std::size_t>(65536, b.max_size() - b.size()));-    b.commit(s.read_some(b.prepare(bytes_to_read), ec));-    if (ec)-      return 0;-  }-}--#endif // defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream,-    typename DynamicBuffer_v1, typename MatchCondition>-inline std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,-    MatchCondition match_condition,-    constraint_t<-      is_match_condition<MatchCondition>::value-    >,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)-{-  asio::error_code ec;-  std::size_t bytes_transferred = read_until(s,-      static_cast<DynamicBuffer_v1&&>(buffers),-      match_condition, ec);-  asio::detail::throw_error(ec, "read_until");-  return bytes_transferred;-}--template <typename SyncReadStream,-    typename DynamicBuffer_v1, typename MatchCondition>-std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,-    MatchCondition match_condition, asio::error_code& ec,-    constraint_t<-      is_match_condition<MatchCondition>::value-    >,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)-{-  decay_t<DynamicBuffer_v1> b(-      static_cast<DynamicBuffer_v1&&>(buffers));--  std::size_t search_position = 0;-  for (;;)-  {-    // Determine the range of the data to be searched.-    typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;-    typedef buffers_iterator<buffers_type> iterator;-    buffers_type data_buffers = b.data();-    iterator begin = iterator::begin(data_buffers);-    iterator start_pos = begin + search_position;-    iterator end = iterator::end(data_buffers);--    // Look for a match.-    std::pair<iterator, bool> result = match_condition(start_pos, end);-    if (result.second)-    {-      // Full match. We're done.-      ec = asio::error_code();-      return result.first - begin;-    }-    else if (result.first != end)-    {-      // Partial match. Next search needs to start from beginning of match.-      search_position = result.first - begin;-    }-    else-    {-      // No match. Next search can start with the new data.-      search_position = end - begin;-    }--    // Check if buffer is full.-    if (b.size() == b.max_size())-    {-      ec = error::not_found;-      return 0;-    }--    // Need more data.-    std::size_t bytes_to_read = std::min<std::size_t>(-          std::max<std::size_t>(512, b.capacity() - b.size()),-          std::min<std::size_t>(65536, b.max_size() - b.size()));-    b.commit(s.read_some(b.prepare(bytes_to_read), ec));-    if (ec)-      return 0;-  }-}--#if !defined(ASIO_NO_IOSTREAM)--template <typename SyncReadStream, typename Allocator>-inline std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b, char delim)-{-  return read_until(s, basic_streambuf_ref<Allocator>(b), delim);-}--template <typename SyncReadStream, typename Allocator>-inline std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b, char delim,-    asio::error_code& ec)-{-  return read_until(s, basic_streambuf_ref<Allocator>(b), delim, ec);-}--template <typename SyncReadStream, typename Allocator>-inline std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b,-    ASIO_STRING_VIEW_PARAM delim)-{-  return read_until(s, basic_streambuf_ref<Allocator>(b), delim);-}--template <typename SyncReadStream, typename Allocator>-inline std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b,-    ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec)-{-  return read_until(s, basic_streambuf_ref<Allocator>(b), delim, ec);-}--#if defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream, typename Allocator, typename Traits>-inline std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b,-    const boost::basic_regex<char, Traits>& expr)-{-  return read_until(s, basic_streambuf_ref<Allocator>(b), expr);-}--template <typename SyncReadStream, typename Allocator, typename Traits>-inline std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b,-    const boost::basic_regex<char, Traits>& expr,-    asio::error_code& ec)-{-  return read_until(s, basic_streambuf_ref<Allocator>(b), expr, ec);-}--#endif // defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream, typename Allocator, typename MatchCondition>-inline std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,-    constraint_t<is_match_condition<MatchCondition>::value>)-{-  return read_until(s, basic_streambuf_ref<Allocator>(b), match_condition);-}--template <typename SyncReadStream, typename Allocator, typename MatchCondition>-inline std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b,-    MatchCondition match_condition, asio::error_code& ec,-    constraint_t<is_match_condition<MatchCondition>::value>)-{-  return read_until(s, basic_streambuf_ref<Allocator>(b), match_condition, ec);-}--#endif // !defined(ASIO_NO_IOSTREAM)-#endif // !defined(ASIO_NO_EXTENSIONS)-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--template <typename SyncReadStream, typename DynamicBuffer_v2>-inline std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v2 buffers, char delim,-    constraint_t<-      is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)-{-  asio::error_code ec;-  std::size_t bytes_transferred = read_until(s,-      static_cast<DynamicBuffer_v2&&>(buffers), delim, ec);-  asio::detail::throw_error(ec, "read_until");-  return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v2>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,-    char delim, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)-{-  DynamicBuffer_v2& b = buffers;--  std::size_t search_position = 0;-  for (;;)-  {-    // Determine the range of the data to be searched.-    typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;-    typedef buffers_iterator<buffers_type> iterator;-    buffers_type data_buffers =-      const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());-    iterator begin = iterator::begin(data_buffers);-    iterator start_pos = begin + search_position;-    iterator end = iterator::end(data_buffers);--    // Look for a match.-    iterator iter = std::find(start_pos, end, delim);-    if (iter != end)-    {-      // Found a match. We're done.-      ec = asio::error_code();-      return iter - begin + 1;-    }-    else-    {-      // No match. Next search can start with the new data.-      search_position = end - begin;-    }--    // Check if buffer is full.-    if (b.size() == b.max_size())-    {-      ec = error::not_found;-      return 0;-    }--    // Need more data.-    std::size_t bytes_to_read = std::min<std::size_t>(-          std::max<std::size_t>(512, b.capacity() - b.size()),-          std::min<std::size_t>(65536, b.max_size() - b.size()));-    std::size_t pos = b.size();-    b.grow(bytes_to_read);-    std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);-    b.shrink(bytes_to_read - bytes_transferred);-    if (ec)-      return 0;-  }-}--template <typename SyncReadStream, typename DynamicBuffer_v2>-inline std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,-    constraint_t<-      is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)-{-  asio::error_code ec;-  std::size_t bytes_transferred = read_until(s,-      static_cast<DynamicBuffer_v2&&>(buffers), delim, ec);-  asio::detail::throw_error(ec, "read_until");-  return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v2>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,-    ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)-{-  DynamicBuffer_v2& b = buffers;--  std::size_t search_position = 0;-  for (;;)-  {-    // Determine the range of the data to be searched.-    typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;-    typedef buffers_iterator<buffers_type> iterator;-    buffers_type data_buffers =-      const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());-    iterator begin = iterator::begin(data_buffers);-    iterator start_pos = begin + search_position;-    iterator end = iterator::end(data_buffers);--    // Look for a match.-    std::pair<iterator, bool> result = detail::partial_search(-        start_pos, end, delim.begin(), delim.end());-    if (result.first != end)-    {-      if (result.second)-      {-        // Full match. We're done.-        ec = asio::error_code();-        return result.first - begin + delim.length();-      }-      else-      {-        // Partial match. Next search needs to start from beginning of match.-        search_position = result.first - begin;-      }-    }-    else-    {-      // No match. Next search can start with the new data.-      search_position = end - begin;-    }--    // Check if buffer is full.-    if (b.size() == b.max_size())-    {-      ec = error::not_found;-      return 0;-    }--    // Need more data.-    std::size_t bytes_to_read = std::min<std::size_t>(-          std::max<std::size_t>(512, b.capacity() - b.size()),-          std::min<std::size_t>(65536, b.max_size() - b.size()));-    std::size_t pos = b.size();-    b.grow(bytes_to_read);-    std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);-    b.shrink(bytes_to_read - bytes_transferred);-    if (ec)-      return 0;-  }-}--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>-inline std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,-    const boost::basic_regex<char, Traits>& expr,-    constraint_t<-      is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)-{-  asio::error_code ec;-  std::size_t bytes_transferred = read_until(s,-      static_cast<DynamicBuffer_v2&&>(buffers), expr, ec);-  asio::detail::throw_error(ec, "read_until");-  return bytes_transferred;-}--template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,-    const boost::basic_regex<char, Traits>& expr, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)-{-  DynamicBuffer_v2& b = buffers;--  std::size_t search_position = 0;-  for (;;)-  {-    // Determine the range of the data to be searched.-    typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;-    typedef buffers_iterator<buffers_type> iterator;-    buffers_type data_buffers =-      const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());-    iterator begin = iterator::begin(data_buffers);-    iterator start_pos = begin + search_position;-    iterator end = iterator::end(data_buffers);--    // Look for a match.-    boost::match_results<iterator,-      typename std::vector<boost::sub_match<iterator>>::allocator_type>-        match_results;-    if (regex_search(start_pos, end, match_results,-          expr, detail::regex_match_flags()))-    {-      if (match_results[0].matched)-      {-        // Full match. We're done.-        ec = asio::error_code();-        return match_results[0].second - begin;-      }-      else-      {-        // Partial match. Next search needs to start from beginning of match.-        search_position = match_results[0].first - begin;-      }-    }-    else-    {-      // No match. Next search can start with the new data.-      search_position = end - begin;-    }--    // Check if buffer is full.-    if (b.size() == b.max_size())-    {-      ec = error::not_found;-      return 0;-    }--    // Need more data.-    std::size_t bytes_to_read = std::min<std::size_t>(-          std::max<std::size_t>(512, b.capacity() - b.size()),-          std::min<std::size_t>(65536, b.max_size() - b.size()));-    std::size_t pos = b.size();-    b.grow(bytes_to_read);-    std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);-    b.shrink(bytes_to_read - bytes_transferred);-    if (ec)-      return 0;-  }-}--#endif // defined(ASIO_HAS_BOOST_REGEX)--template <typename SyncReadStream,-    typename DynamicBuffer_v2, typename MatchCondition>-inline std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v2 buffers, MatchCondition match_condition,-    constraint_t<-      is_match_condition<MatchCondition>::value-    >,-    constraint_t<-      is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)-{-  asio::error_code ec;-  std::size_t bytes_transferred = read_until(s,-      static_cast<DynamicBuffer_v2&&>(buffers),-      match_condition, ec);-  asio::detail::throw_error(ec, "read_until");-  return bytes_transferred;-}--template <typename SyncReadStream,-    typename DynamicBuffer_v2, typename MatchCondition>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,-    MatchCondition match_condition, asio::error_code& ec,-    constraint_t<-      is_match_condition<MatchCondition>::value-    >,-    constraint_t<-      is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)-{-  DynamicBuffer_v2& b = buffers;--  std::size_t search_position = 0;-  for (;;)-  {-    // Determine the range of the data to be searched.-    typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;-    typedef buffers_iterator<buffers_type> iterator;-    buffers_type data_buffers =-      const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());-    iterator begin = iterator::begin(data_buffers);-    iterator start_pos = begin + search_position;-    iterator end = iterator::end(data_buffers);--    // Look for a match.-    std::pair<iterator, bool> result = match_condition(start_pos, end);-    if (result.second)-    {-      // Full match. We're done.-      ec = asio::error_code();-      return result.first - begin;-    }-    else if (result.first != end)-    {-      // Partial match. Next search needs to start from beginning of match.-      search_position = result.first - begin;-    }-    else-    {-      // No match. Next search can start with the new data.-      search_position = end - begin;-    }--    // Check if buffer is full.-    if (b.size() == b.max_size())-    {-      ec = error::not_found;-      return 0;-    }--    // Need more data.-    std::size_t bytes_to_read = std::min<std::size_t>(-          std::max<std::size_t>(512, b.capacity() - b.size()),-          std::min<std::size_t>(65536, b.max_size() - b.size()));-    std::size_t pos = b.size();-    b.grow(bytes_to_read);-    std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);-    b.shrink(bytes_to_read - bytes_transferred);-    if (ec)-      return 0;-  }-}--#endif // !defined(ASIO_NO_EXTENSIONS)--#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--namespace detail-{-  template <typename AsyncReadStream,-      typename DynamicBuffer_v1, typename ReadHandler>-  class read_until_delim_op_v1-    : public base_from_cancellation_state<ReadHandler>-  {-  public:-    template <typename BufferSequence>-    read_until_delim_op_v1(AsyncReadStream& stream,-        BufferSequence&& buffers,-        char delim, ReadHandler& handler)-      : base_from_cancellation_state<ReadHandler>(-          handler, enable_partial_cancellation()),-        stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),-        delim_(delim),-        start_(0),-        search_position_(0),-        handler_(static_cast<ReadHandler&&>(handler))-    {-    }--    read_until_delim_op_v1(const read_until_delim_op_v1& other)-      : base_from_cancellation_state<ReadHandler>(other),-        stream_(other.stream_),-        buffers_(other.buffers_),-        delim_(other.delim_),-        start_(other.start_),-        search_position_(other.search_position_),-        handler_(other.handler_)-    {-    }--    read_until_delim_op_v1(read_until_delim_op_v1&& other)-      : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),-        stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),-        delim_(other.delim_),-        start_(other.start_),-        search_position_(other.search_position_),-        handler_(static_cast<ReadHandler&&>(other.handler_))-    {-    }--    void operator()(asio::error_code ec,-        std::size_t bytes_transferred, int start = 0)-    {-      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();-      std::size_t bytes_to_read;-      switch (start_ = start)-      {-      case 1:-        for (;;)-        {-          {-            // Determine the range of the data to be searched.-            typedef typename DynamicBuffer_v1::const_buffers_type-              buffers_type;-            typedef buffers_iterator<buffers_type> iterator;-            buffers_type data_buffers = buffers_.data();-            iterator begin = iterator::begin(data_buffers);-            iterator start_pos = begin + search_position_;-            iterator end = iterator::end(data_buffers);--            // Look for a match.-            iterator iter = std::find(start_pos, end, delim_);-            if (iter != end)-            {-              // Found a match. We're done.-              search_position_ = iter - begin + 1;-              bytes_to_read = 0;-            }--            // No match yet. Check if buffer is full.-            else if (buffers_.size() == buffers_.max_size())-            {-              search_position_ = not_found;-              bytes_to_read = 0;-            }--            // Need to read some more data.-            else-            {-              // Next search can start with the new data.-              search_position_ = end - begin;-              bytes_to_read = std::min<std::size_t>(-                    std::max<std::size_t>(512,-                      buffers_.capacity() - buffers_.size()),-                    std::min<std::size_t>(65536,-                      buffers_.max_size() - buffers_.size()));-            }-          }--          // Check if we're done.-          if (!start && bytes_to_read == 0)-            break;--          // Start a new asynchronous read operation to obtain more data.-          {-            ASIO_HANDLER_LOCATION((-                  __FILE__, __LINE__, "async_read_until"));-            stream_.async_read_some(buffers_.prepare(bytes_to_read),-                static_cast<read_until_delim_op_v1&&>(*this));-          }-          return; default:-          buffers_.commit(bytes_transferred);-          if (ec || bytes_transferred == 0)-            break;-          if (this->cancelled() != cancellation_type::none)-          {-            ec = error::operation_aborted;-            break;-          }-        }--        const asio::error_code result_ec =-          (search_position_ == not_found)-          ? error::not_found : ec;--        const std::size_t result_n =-          (ec || search_position_ == not_found)-          ? 0 : search_position_;--        static_cast<ReadHandler&&>(handler_)(result_ec, result_n);-      }-    }--  //private:-    AsyncReadStream& stream_;-    DynamicBuffer_v1 buffers_;-    char delim_;-    int start_;-    std::size_t search_position_;-    ReadHandler handler_;-  };--  template <typename AsyncReadStream,-      typename DynamicBuffer_v1, typename ReadHandler>-  inline bool asio_handler_is_continuation(-      read_until_delim_op_v1<AsyncReadStream,-        DynamicBuffer_v1, ReadHandler>* this_handler)-  {-    return this_handler->start_ == 0 ? true-      : asio_handler_cont_helpers::is_continuation(-          this_handler->handler_);-  }--  template <typename AsyncReadStream>-  class initiate_async_read_until_delim_v1-  {-  public:-    typedef typename AsyncReadStream::executor_type executor_type;--    explicit initiate_async_read_until_delim_v1(AsyncReadStream& stream)-      : stream_(stream)-    {-    }--    executor_type get_executor() const noexcept-    {-      return stream_.get_executor();-    }--    template <typename ReadHandler, typename DynamicBuffer_v1>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v1&& buffers,-        char delim) const-    {-      // If you get an error on the following line it means that your handler-      // does not meet the documented type requirements for a ReadHandler.-      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;--      non_const_lvalue<ReadHandler> handler2(handler);-      read_until_delim_op_v1<AsyncReadStream,-        decay_t<DynamicBuffer_v1>,-          decay_t<ReadHandler>>(-            stream_, static_cast<DynamicBuffer_v1&&>(buffers),-            delim, handler2.value)(asio::error_code(), 0, 1);-    }--  private:-    AsyncReadStream& stream_;-  };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename AsyncReadStream, typename DynamicBuffer_v1,-    typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,-    detail::read_until_delim_op_v1<AsyncReadStream,-      DynamicBuffer_v1, ReadHandler>,-    DefaultCandidate>-  : Associator<ReadHandler, DefaultCandidate>-{-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_until_delim_op_v1<AsyncReadStream,-        DynamicBuffer_v1, ReadHandler>& h) noexcept-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(-      const detail::read_until_delim_op_v1<AsyncReadStream,-        DynamicBuffer_v1, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--namespace detail-{-  template <typename AsyncReadStream,-      typename DynamicBuffer_v1, typename ReadHandler>-  class read_until_delim_string_op_v1-    : public base_from_cancellation_state<ReadHandler>-  {-  public:-    template <typename BufferSequence>-    read_until_delim_string_op_v1(AsyncReadStream& stream,-        BufferSequence&& buffers,-        const std::string& delim, ReadHandler& handler)-      : base_from_cancellation_state<ReadHandler>(-          handler, enable_partial_cancellation()),-        stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),-        delim_(delim),-        start_(0),-        search_position_(0),-        handler_(static_cast<ReadHandler&&>(handler))-    {-    }--    read_until_delim_string_op_v1(const read_until_delim_string_op_v1& other)-      : base_from_cancellation_state<ReadHandler>(other),-        stream_(other.stream_),-        buffers_(other.buffers_),-        delim_(other.delim_),-        start_(other.start_),-        search_position_(other.search_position_),-        handler_(other.handler_)-    {-    }--    read_until_delim_string_op_v1(read_until_delim_string_op_v1&& other)-      : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),-        stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),-        delim_(static_cast<std::string&&>(other.delim_)),-        start_(other.start_),-        search_position_(other.search_position_),-        handler_(static_cast<ReadHandler&&>(other.handler_))-    {-    }--    void operator()(asio::error_code ec,-        std::size_t bytes_transferred, int start = 0)-    {-      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();-      std::size_t bytes_to_read;-      switch (start_ = start)-      {-      case 1:-        for (;;)-        {-          {-            // Determine the range of the data to be searched.-            typedef typename DynamicBuffer_v1::const_buffers_type-              buffers_type;-            typedef buffers_iterator<buffers_type> iterator;-            buffers_type data_buffers = buffers_.data();-            iterator begin = iterator::begin(data_buffers);-            iterator start_pos = begin + search_position_;-            iterator end = iterator::end(data_buffers);--            // Look for a match.-            std::pair<iterator, bool> result = detail::partial_search(-                start_pos, end, delim_.begin(), delim_.end());-            if (result.first != end && result.second)-            {-              // Full match. We're done.-              search_position_ = result.first - begin + delim_.length();-              bytes_to_read = 0;-            }--            // No match yet. Check if buffer is full.-            else if (buffers_.size() == buffers_.max_size())-            {-              search_position_ = not_found;-              bytes_to_read = 0;-            }--            // Need to read some more data.-            else-            {-              if (result.first != end)-              {-                // Partial match. Next search needs to start from beginning of-                // match.-                search_position_ = result.first - begin;-              }-              else-              {-                // Next search can start with the new data.-                search_position_ = end - begin;-              }--              bytes_to_read = std::min<std::size_t>(-                    std::max<std::size_t>(512,-                      buffers_.capacity() - buffers_.size()),-                    std::min<std::size_t>(65536,-                      buffers_.max_size() - buffers_.size()));-            }-          }--          // Check if we're done.-          if (!start && bytes_to_read == 0)-            break;--          // Start a new asynchronous read operation to obtain more data.-          {-            ASIO_HANDLER_LOCATION((-                  __FILE__, __LINE__, "async_read_until"));-            stream_.async_read_some(buffers_.prepare(bytes_to_read),-                static_cast<read_until_delim_string_op_v1&&>(*this));-          }-          return; default:-          buffers_.commit(bytes_transferred);-          if (ec || bytes_transferred == 0)-            break;-          if (this->cancelled() != cancellation_type::none)-          {-            ec = error::operation_aborted;-            break;-          }-        }--        const asio::error_code result_ec =-          (search_position_ == not_found)-          ? error::not_found : ec;--        const std::size_t result_n =-          (ec || search_position_ == not_found)-          ? 0 : search_position_;--        static_cast<ReadHandler&&>(handler_)(result_ec, result_n);-      }-    }--  //private:-    AsyncReadStream& stream_;-    DynamicBuffer_v1 buffers_;-    std::string delim_;-    int start_;-    std::size_t search_position_;-    ReadHandler handler_;-  };--  template <typename AsyncReadStream,-      typename DynamicBuffer_v1, typename ReadHandler>-  inline bool asio_handler_is_continuation(-      read_until_delim_string_op_v1<AsyncReadStream,-        DynamicBuffer_v1, ReadHandler>* this_handler)-  {-    return this_handler->start_ == 0 ? true-      : asio_handler_cont_helpers::is_continuation(-          this_handler->handler_);-  }--  template <typename AsyncReadStream>-  class initiate_async_read_until_delim_string_v1-  {-  public:-    typedef typename AsyncReadStream::executor_type executor_type;--    explicit initiate_async_read_until_delim_string_v1(AsyncReadStream& stream)-      : stream_(stream)-    {-    }--    executor_type get_executor() const noexcept-    {-      return stream_.get_executor();-    }--    template <typename ReadHandler, typename DynamicBuffer_v1>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v1&& buffers,-        const std::string& delim) const-    {-      // If you get an error on the following line it means that your handler-      // does not meet the documented type requirements for a ReadHandler.-      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;--      non_const_lvalue<ReadHandler> handler2(handler);-      read_until_delim_string_op_v1<AsyncReadStream,-        decay_t<DynamicBuffer_v1>,-          decay_t<ReadHandler>>(-            stream_, static_cast<DynamicBuffer_v1&&>(buffers),-            delim, handler2.value)(asio::error_code(), 0, 1);-    }--  private:-    AsyncReadStream& stream_;-  };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename AsyncReadStream, typename DynamicBuffer_v1,-    typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,-    detail::read_until_delim_string_op_v1<AsyncReadStream,-      DynamicBuffer_v1, ReadHandler>,-    DefaultCandidate>-  : Associator<ReadHandler, DefaultCandidate>-{-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_until_delim_string_op_v1<-        AsyncReadStream, DynamicBuffer_v1, ReadHandler>& h) noexcept-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(-      const detail::read_until_delim_string_op_v1<-        AsyncReadStream, DynamicBuffer_v1, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)--namespace detail-{-  template <typename AsyncReadStream, typename DynamicBuffer_v1,-      typename RegEx, typename ReadHandler>-  class read_until_expr_op_v1-    : public base_from_cancellation_state<ReadHandler>-  {-  public:-    template <typename BufferSequence, typename Traits>-    read_until_expr_op_v1(AsyncReadStream& stream, BufferSequence&& buffers,-        const boost::basic_regex<char, Traits>& expr, ReadHandler& handler)-      : base_from_cancellation_state<ReadHandler>(-          handler, enable_partial_cancellation()),-        stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),-        expr_(expr),-        start_(0),-        search_position_(0),-        handler_(static_cast<ReadHandler&&>(handler))-    {-    }--    read_until_expr_op_v1(const read_until_expr_op_v1& other)-      : base_from_cancellation_state<ReadHandler>(other),-        stream_(other.stream_),-        buffers_(other.buffers_),-        expr_(other.expr_),-        start_(other.start_),-        search_position_(other.search_position_),-        handler_(other.handler_)-    {-    }--    read_until_expr_op_v1(read_until_expr_op_v1&& other)-      : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),-        stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),-        expr_(other.expr_),-        start_(other.start_),-        search_position_(other.search_position_),-        handler_(static_cast<ReadHandler&&>(other.handler_))-    {-    }--    void operator()(asio::error_code ec,-        std::size_t bytes_transferred, int start = 0)-    {-      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();-      std::size_t bytes_to_read;-      switch (start_ = start)-      {-      case 1:-        for (;;)-        {-          {-            // Determine the range of the data to be searched.-            typedef typename DynamicBuffer_v1::const_buffers_type-              buffers_type;-            typedef buffers_iterator<buffers_type> iterator;-            buffers_type data_buffers = buffers_.data();-            iterator begin = iterator::begin(data_buffers);-            iterator start_pos = begin + search_position_;-            iterator end = iterator::end(data_buffers);--            // Look for a match.-            boost::match_results<iterator,-              typename std::vector<boost::sub_match<iterator>>::allocator_type>-                match_results;-            bool match = regex_search(start_pos, end,-                match_results, expr_, regex_match_flags());-            if (match && match_results[0].matched)-            {-              // Full match. We're done.-              search_position_ = match_results[0].second - begin;-              bytes_to_read = 0;-            }--            // No match yet. Check if buffer is full.-            else if (buffers_.size() == buffers_.max_size())-            {-              search_position_ = not_found;-              bytes_to_read = 0;-            }--            // Need to read some more data.-            else-            {-              if (match)-              {-                // Partial match. Next search needs to start from beginning of-                // match.-                search_position_ = match_results[0].first - begin;-              }-              else-              {-                // Next search can start with the new data.-                search_position_ = end - begin;-              }--              bytes_to_read = std::min<std::size_t>(-                    std::max<std::size_t>(512,-                      buffers_.capacity() - buffers_.size()),-                    std::min<std::size_t>(65536,-                      buffers_.max_size() - buffers_.size()));-            }-          }--          // Check if we're done.-          if (!start && bytes_to_read == 0)-            break;--          // Start a new asynchronous read operation to obtain more data.-          {-            ASIO_HANDLER_LOCATION((-                  __FILE__, __LINE__, "async_read_until"));-            stream_.async_read_some(buffers_.prepare(bytes_to_read),-                static_cast<read_until_expr_op_v1&&>(*this));-          }-          return; default:-          buffers_.commit(bytes_transferred);-          if (ec || bytes_transferred == 0)-            break;-          if (this->cancelled() != cancellation_type::none)-          {-            ec = error::operation_aborted;-            break;-          }-        }--        const asio::error_code result_ec =-          (search_position_ == not_found)-          ? error::not_found : ec;--        const std::size_t result_n =-          (ec || search_position_ == not_found)-          ? 0 : search_position_;--        static_cast<ReadHandler&&>(handler_)(result_ec, result_n);-      }-    }--  //private:-    AsyncReadStream& stream_;-    DynamicBuffer_v1 buffers_;-    RegEx expr_;-    int start_;-    std::size_t search_position_;-    ReadHandler handler_;-  };--  template <typename AsyncReadStream, typename DynamicBuffer_v1,-      typename RegEx, typename ReadHandler>-  inline bool asio_handler_is_continuation(-      read_until_expr_op_v1<AsyncReadStream,-        DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)-  {-    return this_handler->start_ == 0 ? true-      : asio_handler_cont_helpers::is_continuation(-          this_handler->handler_);-  }--  template <typename AsyncReadStream>-  class initiate_async_read_until_expr_v1-  {-  public:-    typedef typename AsyncReadStream::executor_type executor_type;--    explicit initiate_async_read_until_expr_v1(AsyncReadStream& stream)-      : stream_(stream)-    {-    }--    executor_type get_executor() const noexcept-    {-      return stream_.get_executor();-    }--    template <typename ReadHandler, typename DynamicBuffer_v1, typename RegEx>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v1&& buffers, const RegEx& expr) const-    {-      // If you get an error on the following line it means that your handler-      // does not meet the documented type requirements for a ReadHandler.-      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;--      non_const_lvalue<ReadHandler> handler2(handler);-      read_until_expr_op_v1<AsyncReadStream,-        decay_t<DynamicBuffer_v1>,-          RegEx, decay_t<ReadHandler>>(-            stream_, static_cast<DynamicBuffer_v1&&>(buffers),-            expr, handler2.value)(asio::error_code(), 0, 1);-    }--  private:-    AsyncReadStream& stream_;-  };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename AsyncReadStream, typename DynamicBuffer_v1,-    typename RegEx, typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,-    detail::read_until_expr_op_v1<AsyncReadStream,-      DynamicBuffer_v1, RegEx, ReadHandler>,-    DefaultCandidate>-  : Associator<ReadHandler, DefaultCandidate>-{-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_until_expr_op_v1<AsyncReadStream,-        DynamicBuffer_v1, RegEx, ReadHandler>& h) noexcept-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(-      const detail::read_until_expr_op_v1<AsyncReadStream,-        DynamicBuffer_v1, RegEx, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#endif // defined(ASIO_HAS_BOOST_REGEX)--namespace detail-{-  template <typename AsyncReadStream, typename DynamicBuffer_v1,-      typename MatchCondition, typename ReadHandler>-  class read_until_match_op_v1-    : public base_from_cancellation_state<ReadHandler>-  {-  public:-    template <typename BufferSequence>-    read_until_match_op_v1(AsyncReadStream& stream,-        BufferSequence&& buffers,-        MatchCondition match_condition, ReadHandler& handler)-      : base_from_cancellation_state<ReadHandler>(-          handler, enable_partial_cancellation()),-        stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),-        match_condition_(match_condition),-        start_(0),-        search_position_(0),-        handler_(static_cast<ReadHandler&&>(handler))-    {-    }--    read_until_match_op_v1(const read_until_match_op_v1& other)-      : base_from_cancellation_state<ReadHandler>(other),-        stream_(other.stream_),-        buffers_(other.buffers_),-        match_condition_(other.match_condition_),-        start_(other.start_),-        search_position_(other.search_position_),-        handler_(other.handler_)-    {-    }--    read_until_match_op_v1(read_until_match_op_v1&& other)-      : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),-        stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),-        match_condition_(other.match_condition_),-        start_(other.start_),-        search_position_(other.search_position_),-        handler_(static_cast<ReadHandler&&>(other.handler_))-    {-    }--    void operator()(asio::error_code ec,-        std::size_t bytes_transferred, int start = 0)-    {-      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();-      std::size_t bytes_to_read;-      switch (start_ = start)-      {-      case 1:-        for (;;)-        {-          {-            // Determine the range of the data to be searched.-            typedef typename DynamicBuffer_v1::const_buffers_type-              buffers_type;-            typedef buffers_iterator<buffers_type> iterator;-            buffers_type data_buffers = buffers_.data();-            iterator begin = iterator::begin(data_buffers);-            iterator start_pos = begin + search_position_;-            iterator end = iterator::end(data_buffers);--            // Look for a match.-            std::pair<iterator, bool> result = match_condition_(start_pos, end);-            if (result.second)-            {-              // Full match. We're done.-              search_position_ = result.first - begin;-              bytes_to_read = 0;-            }--            // No match yet. Check if buffer is full.-            else if (buffers_.size() == buffers_.max_size())-            {-              search_position_ = not_found;-              bytes_to_read = 0;-            }--            // Need to read some more data.-            else-            {-              if (result.first != end)-              {-                // Partial match. Next search needs to start from beginning of-                // match.-                search_position_ = result.first - begin;-              }-              else-              {-                // Next search can start with the new data.-                search_position_ = end - begin;-              }--              bytes_to_read = std::min<std::size_t>(-                    std::max<std::size_t>(512,-                      buffers_.capacity() - buffers_.size()),-                    std::min<std::size_t>(65536,-                      buffers_.max_size() - buffers_.size()));-            }-          }--          // Check if we're done.-          if (!start && bytes_to_read == 0)-            break;--          // Start a new asynchronous read operation to obtain more data.-          {-            ASIO_HANDLER_LOCATION((-                  __FILE__, __LINE__, "async_read_until"));-            stream_.async_read_some(buffers_.prepare(bytes_to_read),-                static_cast<read_until_match_op_v1&&>(*this));-          }-          return; default:-          buffers_.commit(bytes_transferred);-          if (ec || bytes_transferred == 0)-            break;-          if (this->cancelled() != cancellation_type::none)-          {-            ec = error::operation_aborted;-            break;-          }-        }--        const asio::error_code result_ec =-          (search_position_ == not_found)-          ? error::not_found : ec;--        const std::size_t result_n =-          (ec || search_position_ == not_found)-          ? 0 : search_position_;--        static_cast<ReadHandler&&>(handler_)(result_ec, result_n);-      }-    }--  //private:-    AsyncReadStream& stream_;-    DynamicBuffer_v1 buffers_;-    MatchCondition match_condition_;-    int start_;-    std::size_t search_position_;-    ReadHandler handler_;-  };--  template <typename AsyncReadStream, typename DynamicBuffer_v1,-      typename MatchCondition, typename ReadHandler>-  inline bool asio_handler_is_continuation(-      read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,-        MatchCondition, ReadHandler>* this_handler)-  {-    return this_handler->start_ == 0 ? true-      : asio_handler_cont_helpers::is_continuation(-          this_handler->handler_);-  }--  template <typename AsyncReadStream>-  class initiate_async_read_until_match_v1-  {-  public:-    typedef typename AsyncReadStream::executor_type executor_type;--    explicit initiate_async_read_until_match_v1(AsyncReadStream& stream)-      : stream_(stream)-    {-    }--    executor_type get_executor() const noexcept-    {-      return stream_.get_executor();-    }--    template <typename ReadHandler,-        typename DynamicBuffer_v1, typename MatchCondition>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v1&& buffers,-        MatchCondition match_condition) const-    {-      // If you get an error on the following line it means that your handler-      // does not meet the documented type requirements for a ReadHandler.-      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;--      non_const_lvalue<ReadHandler> handler2(handler);-      read_until_match_op_v1<AsyncReadStream,-        decay_t<DynamicBuffer_v1>,-          MatchCondition, decay_t<ReadHandler>>(-            stream_, static_cast<DynamicBuffer_v1&&>(buffers),-            match_condition, handler2.value)(asio::error_code(), 0, 1);-    }--  private:-    AsyncReadStream& stream_;-  };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename AsyncReadStream, typename DynamicBuffer_v1,-    typename MatchCondition, typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,-    detail::read_until_match_op_v1<AsyncReadStream,-      DynamicBuffer_v1, MatchCondition, ReadHandler>,-    DefaultCandidate>-  : Associator<ReadHandler, DefaultCandidate>-{-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_until_match_op_v1<AsyncReadStream,-        DynamicBuffer_v1, MatchCondition, ReadHandler>& h) noexcept-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(-      const detail::read_until_match_op_v1<AsyncReadStream,-        DynamicBuffer_v1, MatchCondition, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#endif // !defined(ASIO_NO_EXTENSIONS)-#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)--namespace detail-{-  template <typename AsyncReadStream,-      typename DynamicBuffer_v2, typename ReadHandler>-  class read_until_delim_op_v2-    : public base_from_cancellation_state<ReadHandler>-  {-  public:-    template <typename BufferSequence>-    read_until_delim_op_v2(AsyncReadStream& stream,-        BufferSequence&& buffers,-        char delim, ReadHandler& handler)-      : base_from_cancellation_state<ReadHandler>(-          handler, enable_partial_cancellation()),-        stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),-        delim_(delim),-        start_(0),-        search_position_(0),-        bytes_to_read_(0),-        handler_(static_cast<ReadHandler&&>(handler))-    {-    }--    read_until_delim_op_v2(const read_until_delim_op_v2& other)-      : base_from_cancellation_state<ReadHandler>(other),-        stream_(other.stream_),-        buffers_(other.buffers_),-        delim_(other.delim_),-        start_(other.start_),-        search_position_(other.search_position_),-        bytes_to_read_(other.bytes_to_read_),-        handler_(other.handler_)-    {-    }--    read_until_delim_op_v2(read_until_delim_op_v2&& other)-      : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),-        stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),-        delim_(other.delim_),-        start_(other.start_),-        search_position_(other.search_position_),-        bytes_to_read_(other.bytes_to_read_),-        handler_(static_cast<ReadHandler&&>(other.handler_))-    {-    }--    void operator()(asio::error_code ec,-        std::size_t bytes_transferred, int start = 0)-    {-      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();-      std::size_t pos;-      switch (start_ = start)-      {-      case 1:-        for (;;)-        {-          {-            // Determine the range of the data to be searched.-            typedef typename DynamicBuffer_v2::const_buffers_type-              buffers_type;-            typedef buffers_iterator<buffers_type> iterator;-            buffers_type data_buffers =-              const_cast<const DynamicBuffer_v2&>(buffers_).data(-                  0, buffers_.size());-            iterator begin = iterator::begin(data_buffers);-            iterator start_pos = begin + search_position_;-            iterator end = iterator::end(data_buffers);--            // Look for a match.-            iterator iter = std::find(start_pos, end, delim_);-            if (iter != end)-            {-              // Found a match. We're done.-              search_position_ = iter - begin + 1;-              bytes_to_read_ = 0;-            }--            // No match yet. Check if buffer is full.-            else if (buffers_.size() == buffers_.max_size())-            {-              search_position_ = not_found;-              bytes_to_read_ = 0;-            }--            // Need to read some more data.-            else-            {-              // Next search can start with the new data.-              search_position_ = end - begin;-              bytes_to_read_ = std::min<std::size_t>(-                    std::max<std::size_t>(512,-                      buffers_.capacity() - buffers_.size()),-                    std::min<std::size_t>(65536,-                      buffers_.max_size() - buffers_.size()));-            }-          }--          // Check if we're done.-          if (!start && bytes_to_read_ == 0)-            break;--          // Start a new asynchronous read operation to obtain more data.-          pos = buffers_.size();-          buffers_.grow(bytes_to_read_);-          {-            ASIO_HANDLER_LOCATION((-                  __FILE__, __LINE__, "async_read_until"));-            stream_.async_read_some(buffers_.data(pos, bytes_to_read_),-                static_cast<read_until_delim_op_v2&&>(*this));-          }-          return; default:-          buffers_.shrink(bytes_to_read_ - bytes_transferred);-          if (ec || bytes_transferred == 0)-            break;-          if (this->cancelled() != cancellation_type::none)-          {-            ec = error::operation_aborted;-            break;-          }-        }--        const asio::error_code result_ec =-          (search_position_ == not_found)-          ? error::not_found : ec;--        const std::size_t result_n =-          (ec || search_position_ == not_found)-          ? 0 : search_position_;--        static_cast<ReadHandler&&>(handler_)(result_ec, result_n);-      }-    }--  //private:-    AsyncReadStream& stream_;-    DynamicBuffer_v2 buffers_;-    char delim_;-    int start_;-    std::size_t search_position_;-    std::size_t bytes_to_read_;-    ReadHandler handler_;-  };--  template <typename AsyncReadStream,-      typename DynamicBuffer_v2, typename ReadHandler>-  inline bool asio_handler_is_continuation(-      read_until_delim_op_v2<AsyncReadStream,-        DynamicBuffer_v2, ReadHandler>* this_handler)-  {-    return this_handler->start_ == 0 ? true-      : asio_handler_cont_helpers::is_continuation(-          this_handler->handler_);-  }--  template <typename AsyncReadStream>-  class initiate_async_read_until_delim_v2-  {-  public:-    typedef typename AsyncReadStream::executor_type executor_type;--    explicit initiate_async_read_until_delim_v2(AsyncReadStream& stream)-      : stream_(stream)-    {-    }--    executor_type get_executor() const noexcept-    {-      return stream_.get_executor();-    }--    template <typename ReadHandler, typename DynamicBuffer_v2>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v2&& buffers, char delim) const-    {-      // If you get an error on the following line it means that your handler-      // does not meet the documented type requirements for a ReadHandler.-      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;--      non_const_lvalue<ReadHandler> handler2(handler);-      read_until_delim_op_v2<AsyncReadStream,-        decay_t<DynamicBuffer_v2>,-          decay_t<ReadHandler>>(-            stream_, static_cast<DynamicBuffer_v2&&>(buffers),-            delim, handler2.value)(asio::error_code(), 0, 1);-    }--  private:-    AsyncReadStream& stream_;-  };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename AsyncReadStream, typename DynamicBuffer_v2,-    typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,-    detail::read_until_delim_op_v2<AsyncReadStream,-      DynamicBuffer_v2, ReadHandler>,-    DefaultCandidate>-  : Associator<ReadHandler, DefaultCandidate>-{-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_until_delim_op_v2<AsyncReadStream,-        DynamicBuffer_v2, ReadHandler>& h) noexcept-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(-      const detail::read_until_delim_op_v2<AsyncReadStream,-        DynamicBuffer_v2, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--namespace detail-{-  template <typename AsyncReadStream,-      typename DynamicBuffer_v2, typename ReadHandler>-  class read_until_delim_string_op_v2-    : public base_from_cancellation_state<ReadHandler>-  {-  public:-    template <typename BufferSequence>-    read_until_delim_string_op_v2(AsyncReadStream& stream,-        BufferSequence&& buffers,-        const std::string& delim, ReadHandler& handler)-      : base_from_cancellation_state<ReadHandler>(-          handler, enable_partial_cancellation()),-        stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),-        delim_(delim),-        start_(0),-        search_position_(0),-        bytes_to_read_(0),-        handler_(static_cast<ReadHandler&&>(handler))-    {-    }--    read_until_delim_string_op_v2(const read_until_delim_string_op_v2& other)-      : base_from_cancellation_state<ReadHandler>(other),-        stream_(other.stream_),-        buffers_(other.buffers_),-        delim_(other.delim_),-        start_(other.start_),-        search_position_(other.search_position_),-        bytes_to_read_(other.bytes_to_read_),-        handler_(other.handler_)-    {-    }--    read_until_delim_string_op_v2(read_until_delim_string_op_v2&& other)-      : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),-        stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),-        delim_(static_cast<std::string&&>(other.delim_)),-        start_(other.start_),-        search_position_(other.search_position_),-        bytes_to_read_(other.bytes_to_read_),-        handler_(static_cast<ReadHandler&&>(other.handler_))-    {-    }--    void operator()(asio::error_code ec,-        std::size_t bytes_transferred, int start = 0)-    {-      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();-      std::size_t pos;-      switch (start_ = start)-      {-      case 1:-        for (;;)-        {-          {-            // Determine the range of the data to be searched.-            typedef typename DynamicBuffer_v2::const_buffers_type-              buffers_type;-            typedef buffers_iterator<buffers_type> iterator;-            buffers_type data_buffers =-              const_cast<const DynamicBuffer_v2&>(buffers_).data(-                  0, buffers_.size());-            iterator begin = iterator::begin(data_buffers);-            iterator start_pos = begin + search_position_;-            iterator end = iterator::end(data_buffers);--            // Look for a match.-            std::pair<iterator, bool> result = detail::partial_search(-                start_pos, end, delim_.begin(), delim_.end());-            if (result.first != end && result.second)-            {-              // Full match. We're done.-              search_position_ = result.first - begin + delim_.length();-              bytes_to_read_ = 0;-            }--            // No match yet. Check if buffer is full.-            else if (buffers_.size() == buffers_.max_size())-            {-              search_position_ = not_found;-              bytes_to_read_ = 0;-            }--            // Need to read some more data.-            else-            {-              if (result.first != end)-              {-                // Partial match. Next search needs to start from beginning of-                // match.-                search_position_ = result.first - begin;-              }-              else-              {-                // Next search can start with the new data.-                search_position_ = end - begin;-              }--              bytes_to_read_ = std::min<std::size_t>(-                    std::max<std::size_t>(512,-                      buffers_.capacity() - buffers_.size()),-                    std::min<std::size_t>(65536,-                      buffers_.max_size() - buffers_.size()));-            }-          }--          // Check if we're done.-          if (!start && bytes_to_read_ == 0)-            break;--          // Start a new asynchronous read operation to obtain more data.-          pos = buffers_.size();-          buffers_.grow(bytes_to_read_);-          {-            ASIO_HANDLER_LOCATION((-                  __FILE__, __LINE__, "async_read_until"));-            stream_.async_read_some(buffers_.data(pos, bytes_to_read_),-                static_cast<read_until_delim_string_op_v2&&>(*this));-          }-          return; default:-          buffers_.shrink(bytes_to_read_ - bytes_transferred);-          if (ec || bytes_transferred == 0)-            break;-          if (this->cancelled() != cancellation_type::none)-          {-            ec = error::operation_aborted;-            break;-          }-        }--        const asio::error_code result_ec =-          (search_position_ == not_found)-          ? error::not_found : ec;--        const std::size_t result_n =-          (ec || search_position_ == not_found)-          ? 0 : search_position_;--        static_cast<ReadHandler&&>(handler_)(result_ec, result_n);-      }-    }--  //private:-    AsyncReadStream& stream_;-    DynamicBuffer_v2 buffers_;-    std::string delim_;-    int start_;-    std::size_t search_position_;-    std::size_t bytes_to_read_;-    ReadHandler handler_;-  };--  template <typename AsyncReadStream,-      typename DynamicBuffer_v2, typename ReadHandler>-  inline bool asio_handler_is_continuation(-      read_until_delim_string_op_v2<AsyncReadStream,-        DynamicBuffer_v2, ReadHandler>* this_handler)-  {-    return this_handler->start_ == 0 ? true-      : asio_handler_cont_helpers::is_continuation(-          this_handler->handler_);-  }--  template <typename AsyncReadStream>-  class initiate_async_read_until_delim_string_v2-  {-  public:-    typedef typename AsyncReadStream::executor_type executor_type;--    explicit initiate_async_read_until_delim_string_v2(AsyncReadStream& stream)-      : stream_(stream)-    {-    }--    executor_type get_executor() const noexcept-    {-      return stream_.get_executor();-    }--    template <typename ReadHandler, typename DynamicBuffer_v2>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v2&& buffers,-        const std::string& delim) const-    {-      // If you get an error on the following line it means that your handler-      // does not meet the documented type requirements for a ReadHandler.-      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;--      non_const_lvalue<ReadHandler> handler2(handler);-      read_until_delim_string_op_v2<AsyncReadStream,-        decay_t<DynamicBuffer_v2>,-          decay_t<ReadHandler>>(-            stream_, static_cast<DynamicBuffer_v2&&>(buffers),-            delim, handler2.value)(asio::error_code(), 0, 1);-    }--  private:-    AsyncReadStream& stream_;-  };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename AsyncReadStream, typename DynamicBuffer_v2,-    typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,-    detail::read_until_delim_string_op_v2<AsyncReadStream,-      DynamicBuffer_v2, ReadHandler>,-    DefaultCandidate>-  : Associator<ReadHandler, DefaultCandidate>-{-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_until_delim_string_op_v2<-        AsyncReadStream, DynamicBuffer_v2, ReadHandler>& h) noexcept-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(-      const detail::read_until_delim_string_op_v2<-        AsyncReadStream, DynamicBuffer_v2, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#if !defined(ASIO_NO_EXTENSIONS)-#if defined(ASIO_HAS_BOOST_REGEX)--namespace detail-{-  template <typename AsyncReadStream, typename DynamicBuffer_v2,-      typename RegEx, typename ReadHandler>-  class read_until_expr_op_v2-    : public base_from_cancellation_state<ReadHandler>-  {-  public:-    template <typename BufferSequence, typename Traits>-    read_until_expr_op_v2(AsyncReadStream& stream, BufferSequence&& buffers,-        const boost::basic_regex<char, Traits>& expr, ReadHandler& handler)-      : base_from_cancellation_state<ReadHandler>(-          handler, enable_partial_cancellation()),-        stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),-        expr_(expr),-        start_(0),-        search_position_(0),-        bytes_to_read_(0),-        handler_(static_cast<ReadHandler&&>(handler))-    {-    }--    read_until_expr_op_v2(const read_until_expr_op_v2& other)-      : base_from_cancellation_state<ReadHandler>(other),-        stream_(other.stream_),-        buffers_(other.buffers_),-        expr_(other.expr_),-        start_(other.start_),-        search_position_(other.search_position_),-        bytes_to_read_(other.bytes_to_read_),-        handler_(other.handler_)-    {-    }--    read_until_expr_op_v2(read_until_expr_op_v2&& other)-      : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),-        stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),-        expr_(other.expr_),-        start_(other.start_),-        search_position_(other.search_position_),-        bytes_to_read_(other.bytes_to_read_),-        handler_(static_cast<ReadHandler&&>(other.handler_))-    {-    }--    void operator()(asio::error_code ec,-        std::size_t bytes_transferred, int start = 0)-    {-      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();-      std::size_t pos;-      switch (start_ = start)-      {-      case 1:-        for (;;)-        {-          {-            // Determine the range of the data to be searched.-            typedef typename DynamicBuffer_v2::const_buffers_type-              buffers_type;-            typedef buffers_iterator<buffers_type> iterator;-            buffers_type data_buffers =-              const_cast<const DynamicBuffer_v2&>(buffers_).data(-                  0, buffers_.size());-            iterator begin = iterator::begin(data_buffers);-            iterator start_pos = begin + search_position_;-            iterator end = iterator::end(data_buffers);--            // Look for a match.-            boost::match_results<iterator,-              typename std::vector<boost::sub_match<iterator>>::allocator_type>-                match_results;-            bool match = regex_search(start_pos, end,-                match_results, expr_, regex_match_flags());-            if (match && match_results[0].matched)-            {-              // Full match. We're done.-              search_position_ = match_results[0].second - begin;-              bytes_to_read_ = 0;-            }--            // No match yet. Check if buffer is full.-            else if (buffers_.size() == buffers_.max_size())-            {-              search_position_ = not_found;-              bytes_to_read_ = 0;-            }--            // Need to read some more data.-            else-            {-              if (match)-              {-                // Partial match. Next search needs to start from beginning of-                // match.-                search_position_ = match_results[0].first - begin;-              }-              else-              {-                // Next search can start with the new data.-                search_position_ = end - begin;-              }--              bytes_to_read_ = std::min<std::size_t>(-                    std::max<std::size_t>(512,-                      buffers_.capacity() - buffers_.size()),-                    std::min<std::size_t>(65536,-                      buffers_.max_size() - buffers_.size()));-            }-          }--          // Check if we're done.-          if (!start && bytes_to_read_ == 0)-            break;--          // Start a new asynchronous read operation to obtain more data.-          pos = buffers_.size();-          buffers_.grow(bytes_to_read_);-          {-            ASIO_HANDLER_LOCATION((-                  __FILE__, __LINE__, "async_read_until"));-            stream_.async_read_some(buffers_.data(pos, bytes_to_read_),-                static_cast<read_until_expr_op_v2&&>(*this));-          }-          return; default:-          buffers_.shrink(bytes_to_read_ - bytes_transferred);-          if (ec || bytes_transferred == 0)-            break;-          if (this->cancelled() != cancellation_type::none)-          {-            ec = error::operation_aborted;-            break;-          }-        }--        const asio::error_code result_ec =-          (search_position_ == not_found)-          ? error::not_found : ec;--        const std::size_t result_n =-          (ec || search_position_ == not_found)-          ? 0 : search_position_;--        static_cast<ReadHandler&&>(handler_)(result_ec, result_n);-      }-    }--  //private:-    AsyncReadStream& stream_;-    DynamicBuffer_v2 buffers_;-    RegEx expr_;-    int start_;-    std::size_t search_position_;-    std::size_t bytes_to_read_;-    ReadHandler handler_;-  };--  template <typename AsyncReadStream, typename DynamicBuffer_v2,-      typename RegEx, typename ReadHandler>-  inline bool asio_handler_is_continuation(-      read_until_expr_op_v2<AsyncReadStream,-        DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)-  {-    return this_handler->start_ == 0 ? true-      : asio_handler_cont_helpers::is_continuation(-          this_handler->handler_);-  }--  template <typename AsyncReadStream>-  class initiate_async_read_until_expr_v2-  {-  public:-    typedef typename AsyncReadStream::executor_type executor_type;--    explicit initiate_async_read_until_expr_v2(AsyncReadStream& stream)-      : stream_(stream)-    {-    }--    executor_type get_executor() const noexcept-    {-      return stream_.get_executor();-    }--    template <typename ReadHandler, typename DynamicBuffer_v2, typename RegEx>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v2&& buffers,-        const RegEx& expr) const-    {-      // If you get an error on the following line it means that your handler-      // does not meet the documented type requirements for a ReadHandler.-      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;--      non_const_lvalue<ReadHandler> handler2(handler);-      read_until_expr_op_v2<AsyncReadStream,-        decay_t<DynamicBuffer_v2>,-          RegEx, decay_t<ReadHandler>>(-            stream_, static_cast<DynamicBuffer_v2&&>(buffers),-            expr, handler2.value)(asio::error_code(), 0, 1);-    }--  private:-    AsyncReadStream& stream_;-  };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename AsyncReadStream, typename DynamicBuffer_v2,-    typename RegEx, typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,-    detail::read_until_expr_op_v2<AsyncReadStream,-      DynamicBuffer_v2, RegEx, ReadHandler>,-    DefaultCandidate>-  : Associator<ReadHandler, DefaultCandidate>-{-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_until_expr_op_v2<AsyncReadStream,-        DynamicBuffer_v2, RegEx, ReadHandler>& h) noexcept-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(-      const detail::read_until_expr_op_v2<AsyncReadStream,-        DynamicBuffer_v2, RegEx, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)--#endif // defined(ASIO_HAS_BOOST_REGEX)--namespace detail-{-  template <typename AsyncReadStream, typename DynamicBuffer_v2,-      typename MatchCondition, typename ReadHandler>-  class read_until_match_op_v2-    : public base_from_cancellation_state<ReadHandler>-  {-  public:-    template <typename BufferSequence>-    read_until_match_op_v2(AsyncReadStream& stream,-        BufferSequence&& buffers,-        MatchCondition match_condition, ReadHandler& handler)-      : base_from_cancellation_state<ReadHandler>(-          handler, enable_partial_cancellation()),-        stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),-        match_condition_(match_condition),-        start_(0),-        search_position_(0),-        bytes_to_read_(0),-        handler_(static_cast<ReadHandler&&>(handler))-    {-    }--    read_until_match_op_v2(const read_until_match_op_v2& other)-      : base_from_cancellation_state<ReadHandler>(other),-        stream_(other.stream_),-        buffers_(other.buffers_),-        match_condition_(other.match_condition_),-        start_(other.start_),-        search_position_(other.search_position_),-        bytes_to_read_(other.bytes_to_read_),-        handler_(other.handler_)-    {-    }--    read_until_match_op_v2(read_until_match_op_v2&& other)-      : base_from_cancellation_state<ReadHandler>(-          static_cast<base_from_cancellation_state<ReadHandler>&&>(other)),-        stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),-        match_condition_(other.match_condition_),-        start_(other.start_),-        search_position_(other.search_position_),-        bytes_to_read_(other.bytes_to_read_),-        handler_(static_cast<ReadHandler&&>(other.handler_))-    {-    }--    void operator()(asio::error_code ec,-        std::size_t bytes_transferred, int start = 0)-    {-      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();-      std::size_t pos;-      switch (start_ = start)-      {-      case 1:-        for (;;)-        {-          {-            // Determine the range of the data to be searched.-            typedef typename DynamicBuffer_v2::const_buffers_type-              buffers_type;-            typedef buffers_iterator<buffers_type> iterator;-            buffers_type data_buffers =-              const_cast<const DynamicBuffer_v2&>(buffers_).data(-                  0, buffers_.size());-            iterator begin = iterator::begin(data_buffers);-            iterator start_pos = begin + search_position_;-            iterator end = iterator::end(data_buffers);--            // Look for a match.-            std::pair<iterator, bool> result = match_condition_(start_pos, end);-            if (result.second)-            {-              // Full match. We're done.-              search_position_ = result.first - begin;-              bytes_to_read_ = 0;-            }--            // No match yet. Check if buffer is full.-            else if (buffers_.size() == buffers_.max_size())-            {-              search_position_ = not_found;-              bytes_to_read_ = 0;-            }--            // Need to read some more data.-            else-            {-              if (result.first != end)-              {-                // Partial match. Next search needs to start from beginning of-                // match.-                search_position_ = result.first - begin;-              }-              else-              {-                // Next search can start with the new data.-                search_position_ = end - begin;-              }--              bytes_to_read_ = std::min<std::size_t>(-                    std::max<std::size_t>(512,-                      buffers_.capacity() - buffers_.size()),-                    std::min<std::size_t>(65536,-                      buffers_.max_size() - buffers_.size()));-            }-          }--          // Check if we're done.-          if (!start && bytes_to_read_ == 0)-            break;--          // Start a new asynchronous read operation to obtain more data.-          pos = buffers_.size();-          buffers_.grow(bytes_to_read_);-          {-            ASIO_HANDLER_LOCATION((-                  __FILE__, __LINE__, "async_read_until"));-            stream_.async_read_some(buffers_.data(pos, bytes_to_read_),-                static_cast<read_until_match_op_v2&&>(*this));-          }-          return; default:-          buffers_.shrink(bytes_to_read_ - bytes_transferred);-          if (ec || bytes_transferred == 0)-            break;-          if (this->cancelled() != cancellation_type::none)-          {-            ec = error::operation_aborted;-            break;-          }-        }--        const asio::error_code result_ec =-          (search_position_ == not_found)-          ? error::not_found : ec;--        const std::size_t result_n =-          (ec || search_position_ == not_found)-          ? 0 : search_position_;--        static_cast<ReadHandler&&>(handler_)(result_ec, result_n);-      }-    }--  //private:-    AsyncReadStream& stream_;-    DynamicBuffer_v2 buffers_;-    MatchCondition match_condition_;-    int start_;-    std::size_t search_position_;-    std::size_t bytes_to_read_;-    ReadHandler handler_;-  };--  template <typename AsyncReadStream, typename DynamicBuffer_v2,-      typename MatchCondition, typename ReadHandler>-  inline bool asio_handler_is_continuation(-      read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,-        MatchCondition, ReadHandler>* this_handler)-  {-    return this_handler->start_ == 0 ? true-      : asio_handler_cont_helpers::is_continuation(-          this_handler->handler_);-  }--  template <typename AsyncReadStream>-  class initiate_async_read_until_match_v2-  {-  public:-    typedef typename AsyncReadStream::executor_type executor_type;--    explicit initiate_async_read_until_match_v2(AsyncReadStream& stream)-      : stream_(stream)-    {-    }--    executor_type get_executor() const noexcept-    {-      return stream_.get_executor();-    }--    template <typename ReadHandler,-        typename DynamicBuffer_v2, typename MatchCondition>-    void operator()(ReadHandler&& handler,-        DynamicBuffer_v2&& buffers,-        MatchCondition match_condition) const-    {-      // If you get an error on the following line it means that your handler-      // does not meet the documented type requirements for a ReadHandler.-      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;--      non_const_lvalue<ReadHandler> handler2(handler);-      read_until_match_op_v2<AsyncReadStream, decay_t<DynamicBuffer_v2>,-        MatchCondition, decay_t<ReadHandler>>(-          stream_, static_cast<DynamicBuffer_v2&&>(buffers),-          match_condition, handler2.value)(asio::error_code(), 0, 1);-    }--  private:-    AsyncReadStream& stream_;-  };-} // namespace detail--#if !defined(GENERATING_DOCUMENTATION)--template <template <typename, typename> class Associator,-    typename AsyncReadStream, typename DynamicBuffer_v2,-    typename MatchCondition, typename ReadHandler, typename DefaultCandidate>-struct associator<Associator,-    detail::read_until_match_op_v2<AsyncReadStream,-      DynamicBuffer_v2, MatchCondition, ReadHandler>,-    DefaultCandidate>-  : Associator<ReadHandler, DefaultCandidate>-{-  static typename Associator<ReadHandler, DefaultCandidate>::type get(-      const detail::read_until_match_op_v2<AsyncReadStream,-        DynamicBuffer_v2, MatchCondition, ReadHandler>& h) noexcept-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);-  }--  static auto get(-      const detail::read_until_match_op_v2<AsyncReadStream,-        DynamicBuffer_v2, MatchCondition, ReadHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c))-  {-    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);-  }-};--#endif // !defined(GENERATING_DOCUMENTATION)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_IMPL_READ_UNTIL_HPP+#define ASIO_IMPL_READ_UNTIL_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include <algorithm>+#include <string>+#include <vector>+#include <utility>+#include "asio/associator.hpp"+#include "asio/buffer.hpp"+#include "asio/buffers_iterator.hpp"+#include "asio/detail/base_from_cancellation_state.hpp"+#include "asio/detail/bind_handler.hpp"+#include "asio/detail/handler_alloc_helpers.hpp"+#include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp"+#include "asio/detail/handler_tracking.hpp"+#include "asio/detail/handler_type_requirements.hpp"+#include "asio/detail/limits.hpp"+#include "asio/detail/non_const_lvalue.hpp"+#include "asio/detail/throw_error.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++namespace detail+{+  // Algorithm that finds a subsequence of equal values in a sequence. Returns+  // (iterator,true) if a full match was found, in which case the iterator+  // points to the beginning of the match. Returns (iterator,false) if a+  // partial match was found at the end of the first sequence, in which case+  // the iterator points to the beginning of the partial match. Returns+  // (last1,false) if no full or partial match was found.+  template <typename Iterator1, typename Iterator2>+  std::pair<Iterator1, bool> partial_search(+      Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)+  {+    for (Iterator1 iter1 = first1; iter1 != last1; ++iter1)+    {+      Iterator1 test_iter1 = iter1;+      Iterator2 test_iter2 = first2;+      for (;; ++test_iter1, ++test_iter2)+      {+        if (test_iter2 == last2)+          return std::make_pair(iter1, true);+        if (test_iter1 == last1)+        {+          if (test_iter2 != first2)+            return std::make_pair(iter1, false);+          else+            break;+        }+        if (*test_iter1 != *test_iter2)+          break;+      }+    }+    return std::make_pair(last1, false);+  }+} // namespace detail++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++template <typename SyncReadStream, typename DynamicBuffer_v1>+inline std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+{+  asio::error_code ec;+  std::size_t bytes_transferred = read_until(s,+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, ec);+  asio::detail::throw_error(ec, "read_until");+  return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    char delim, asio::error_code& ec,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+{+  typename decay<DynamicBuffer_v1>::type b(+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));++  std::size_t search_position = 0;+  for (;;)+  {+    // Determine the range of the data to be searched.+    typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;+    typedef buffers_iterator<buffers_type> iterator;+    buffers_type data_buffers = b.data();+    iterator begin = iterator::begin(data_buffers);+    iterator start_pos = begin + search_position;+    iterator end = iterator::end(data_buffers);++    // Look for a match.+    iterator iter = std::find(start_pos, end, delim);+    if (iter != end)+    {+      // Found a match. We're done.+      ec = asio::error_code();+      return iter - begin + 1;+    }+    else+    {+      // No match. Next search can start with the new data.+      search_position = end - begin;+    }++    // Check if buffer is full.+    if (b.size() == b.max_size())+    {+      ec = error::not_found;+      return 0;+    }++    // Need more data.+    std::size_t bytes_to_read = std::min<std::size_t>(+          std::max<std::size_t>(512, b.capacity() - b.size()),+          std::min<std::size_t>(65536, b.max_size() - b.size()));+    b.commit(s.read_some(b.prepare(bytes_to_read), ec));+    if (ec)+      return 0;+  }+}++template <typename SyncReadStream, typename DynamicBuffer_v1>+inline std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    ASIO_STRING_VIEW_PARAM delim,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+{+  asio::error_code ec;+  std::size_t bytes_transferred = read_until(s,+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, ec);+  asio::detail::throw_error(ec, "read_until");+  return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+{+  typename decay<DynamicBuffer_v1>::type b(+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));++  std::size_t search_position = 0;+  for (;;)+  {+    // Determine the range of the data to be searched.+    typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;+    typedef buffers_iterator<buffers_type> iterator;+    buffers_type data_buffers = b.data();+    iterator begin = iterator::begin(data_buffers);+    iterator start_pos = begin + search_position;+    iterator end = iterator::end(data_buffers);++    // Look for a match.+    std::pair<iterator, bool> result = detail::partial_search(+        start_pos, end, delim.begin(), delim.end());+    if (result.first != end)+    {+      if (result.second)+      {+        // Full match. We're done.+        ec = asio::error_code();+        return result.first - begin + delim.length();+      }+      else+      {+        // Partial match. Next search needs to start from beginning of match.+        search_position = result.first - begin;+      }+    }+    else+    {+      // No match. Next search can start with the new data.+      search_position = end - begin;+    }++    // Check if buffer is full.+    if (b.size() == b.max_size())+    {+      ec = error::not_found;+      return 0;+    }++    // Need more data.+    std::size_t bytes_to_read = std::min<std::size_t>(+          std::max<std::size_t>(512, b.capacity() - b.size()),+          std::min<std::size_t>(65536, b.max_size() - b.size()));+    b.commit(s.read_some(b.prepare(bytes_to_read), ec));+    if (ec)+      return 0;+  }+}++#if !defined(ASIO_NO_EXTENSIONS)+#if defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream, typename DynamicBuffer_v1>+inline std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    const boost::regex& expr,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+{+  asio::error_code ec;+  std::size_t bytes_transferred = read_until(s,+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr, ec);+  asio::detail::throw_error(ec, "read_until");+  return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    const boost::regex& expr, asio::error_code& ec,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+{+  typename decay<DynamicBuffer_v1>::type b(+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));++  std::size_t search_position = 0;+  for (;;)+  {+    // Determine the range of the data to be searched.+    typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;+    typedef buffers_iterator<buffers_type> iterator;+    buffers_type data_buffers = b.data();+    iterator begin = iterator::begin(data_buffers);+    iterator start_pos = begin + search_position;+    iterator end = iterator::end(data_buffers);++    // Look for a match.+    boost::match_results<iterator,+      typename std::vector<boost::sub_match<iterator> >::allocator_type>+        match_results;+    if (regex_search(start_pos, end, match_results, expr,+          boost::match_default | boost::match_partial))+    {+      if (match_results[0].matched)+      {+        // Full match. We're done.+        ec = asio::error_code();+        return match_results[0].second - begin;+      }+      else+      {+        // Partial match. Next search needs to start from beginning of match.+        search_position = match_results[0].first - begin;+      }+    }+    else+    {+      // No match. Next search can start with the new data.+      search_position = end - begin;+    }++    // Check if buffer is full.+    if (b.size() == b.max_size())+    {+      ec = error::not_found;+      return 0;+    }++    // Need more data.+    std::size_t bytes_to_read = std::min<std::size_t>(+          std::max<std::size_t>(512, b.capacity() - b.size()),+          std::min<std::size_t>(65536, b.max_size() - b.size()));+    b.commit(s.read_some(b.prepare(bytes_to_read), ec));+    if (ec)+      return 0;+  }+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream,+    typename DynamicBuffer_v1, typename MatchCondition>+inline std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    MatchCondition match_condition,+    typename constraint<+      is_match_condition<MatchCondition>::value+    >::type,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+{+  asio::error_code ec;+  std::size_t bytes_transferred = read_until(s,+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+      match_condition, ec);+  asio::detail::throw_error(ec, "read_until");+  return bytes_transferred;+}++template <typename SyncReadStream,+    typename DynamicBuffer_v1, typename MatchCondition>+std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    MatchCondition match_condition, asio::error_code& ec,+    typename constraint<+      is_match_condition<MatchCondition>::value+    >::type,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+{+  typename decay<DynamicBuffer_v1>::type b(+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));++  std::size_t search_position = 0;+  for (;;)+  {+    // Determine the range of the data to be searched.+    typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;+    typedef buffers_iterator<buffers_type> iterator;+    buffers_type data_buffers = b.data();+    iterator begin = iterator::begin(data_buffers);+    iterator start_pos = begin + search_position;+    iterator end = iterator::end(data_buffers);++    // Look for a match.+    std::pair<iterator, bool> result = match_condition(start_pos, end);+    if (result.second)+    {+      // Full match. We're done.+      ec = asio::error_code();+      return result.first - begin;+    }+    else if (result.first != end)+    {+      // Partial match. Next search needs to start from beginning of match.+      search_position = result.first - begin;+    }+    else+    {+      // No match. Next search can start with the new data.+      search_position = end - begin;+    }++    // Check if buffer is full.+    if (b.size() == b.max_size())+    {+      ec = error::not_found;+      return 0;+    }++    // Need more data.+    std::size_t bytes_to_read = std::min<std::size_t>(+          std::max<std::size_t>(512, b.capacity() - b.size()),+          std::min<std::size_t>(65536, b.max_size() - b.size()));+    b.commit(s.read_some(b.prepare(bytes_to_read), ec));+    if (ec)+      return 0;+  }+}++#if !defined(ASIO_NO_IOSTREAM)++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+    asio::basic_streambuf<Allocator>& b, char delim)+{+  return read_until(s, basic_streambuf_ref<Allocator>(b), delim);+}++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+    asio::basic_streambuf<Allocator>& b, char delim,+    asio::error_code& ec)+{+  return read_until(s, basic_streambuf_ref<Allocator>(b), delim, ec);+}++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+    asio::basic_streambuf<Allocator>& b,+    ASIO_STRING_VIEW_PARAM delim)+{+  return read_until(s, basic_streambuf_ref<Allocator>(b), delim);+}++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+    asio::basic_streambuf<Allocator>& b,+    ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec)+{+  return read_until(s, basic_streambuf_ref<Allocator>(b), delim, ec);+}++#if defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+    asio::basic_streambuf<Allocator>& b, const boost::regex& expr)+{+  return read_until(s, basic_streambuf_ref<Allocator>(b), expr);+}++template <typename SyncReadStream, typename Allocator>+inline std::size_t read_until(SyncReadStream& s,+    asio::basic_streambuf<Allocator>& b, const boost::regex& expr,+    asio::error_code& ec)+{+  return read_until(s, basic_streambuf_ref<Allocator>(b), expr, ec);+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream, typename Allocator, typename MatchCondition>+inline std::size_t read_until(SyncReadStream& s,+    asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,+    typename constraint<is_match_condition<MatchCondition>::value>::type)+{+  return read_until(s, basic_streambuf_ref<Allocator>(b), match_condition);+}++template <typename SyncReadStream, typename Allocator, typename MatchCondition>+inline std::size_t read_until(SyncReadStream& s,+    asio::basic_streambuf<Allocator>& b,+    MatchCondition match_condition, asio::error_code& ec,+    typename constraint<is_match_condition<MatchCondition>::value>::type)+{+  return read_until(s, basic_streambuf_ref<Allocator>(b), match_condition, ec);+}++#endif // !defined(ASIO_NO_IOSTREAM)+#endif // !defined(ASIO_NO_EXTENSIONS)+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++template <typename SyncReadStream, typename DynamicBuffer_v2>+inline std::size_t read_until(SyncReadStream& s,+    DynamicBuffer_v2 buffers, char delim,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+{+  asio::error_code ec;+  std::size_t bytes_transferred = read_until(s,+      ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, ec);+  asio::detail::throw_error(ec, "read_until");+  return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v2>+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,+    char delim, asio::error_code& ec,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+{+  DynamicBuffer_v2& b = buffers;++  std::size_t search_position = 0;+  for (;;)+  {+    // Determine the range of the data to be searched.+    typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;+    typedef buffers_iterator<buffers_type> iterator;+    buffers_type data_buffers =+      const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());+    iterator begin = iterator::begin(data_buffers);+    iterator start_pos = begin + search_position;+    iterator end = iterator::end(data_buffers);++    // Look for a match.+    iterator iter = std::find(start_pos, end, delim);+    if (iter != end)+    {+      // Found a match. We're done.+      ec = asio::error_code();+      return iter - begin + 1;+    }+    else+    {+      // No match. Next search can start with the new data.+      search_position = end - begin;+    }++    // Check if buffer is full.+    if (b.size() == b.max_size())+    {+      ec = error::not_found;+      return 0;+    }++    // Need more data.+    std::size_t bytes_to_read = std::min<std::size_t>(+          std::max<std::size_t>(512, b.capacity() - b.size()),+          std::min<std::size_t>(65536, b.max_size() - b.size()));+    std::size_t pos = b.size();+    b.grow(bytes_to_read);+    std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);+    b.shrink(bytes_to_read - bytes_transferred);+    if (ec)+      return 0;+  }+}++template <typename SyncReadStream, typename DynamicBuffer_v2>+inline std::size_t read_until(SyncReadStream& s,+    DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+{+  asio::error_code ec;+  std::size_t bytes_transferred = read_until(s,+      ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, ec);+  asio::detail::throw_error(ec, "read_until");+  return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v2>+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,+    ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+{+  DynamicBuffer_v2& b = buffers;++  std::size_t search_position = 0;+  for (;;)+  {+    // Determine the range of the data to be searched.+    typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;+    typedef buffers_iterator<buffers_type> iterator;+    buffers_type data_buffers =+      const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());+    iterator begin = iterator::begin(data_buffers);+    iterator start_pos = begin + search_position;+    iterator end = iterator::end(data_buffers);++    // Look for a match.+    std::pair<iterator, bool> result = detail::partial_search(+        start_pos, end, delim.begin(), delim.end());+    if (result.first != end)+    {+      if (result.second)+      {+        // Full match. We're done.+        ec = asio::error_code();+        return result.first - begin + delim.length();+      }+      else+      {+        // Partial match. Next search needs to start from beginning of match.+        search_position = result.first - begin;+      }+    }+    else+    {+      // No match. Next search can start with the new data.+      search_position = end - begin;+    }++    // Check if buffer is full.+    if (b.size() == b.max_size())+    {+      ec = error::not_found;+      return 0;+    }++    // Need more data.+    std::size_t bytes_to_read = std::min<std::size_t>(+          std::max<std::size_t>(512, b.capacity() - b.size()),+          std::min<std::size_t>(65536, b.max_size() - b.size()));+    std::size_t pos = b.size();+    b.grow(bytes_to_read);+    std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);+    b.shrink(bytes_to_read - bytes_transferred);+    if (ec)+      return 0;+  }+}++#if !defined(ASIO_NO_EXTENSIONS)+#if defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream, typename DynamicBuffer_v2>+inline std::size_t read_until(SyncReadStream& s,+    DynamicBuffer_v2 buffers, const boost::regex& expr,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+{+  asio::error_code ec;+  std::size_t bytes_transferred = read_until(s,+      ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr, ec);+  asio::detail::throw_error(ec, "read_until");+  return bytes_transferred;+}++template <typename SyncReadStream, typename DynamicBuffer_v2>+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,+    const boost::regex& expr, asio::error_code& ec,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+{+  DynamicBuffer_v2& b = buffers;++  std::size_t search_position = 0;+  for (;;)+  {+    // Determine the range of the data to be searched.+    typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;+    typedef buffers_iterator<buffers_type> iterator;+    buffers_type data_buffers =+      const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());+    iterator begin = iterator::begin(data_buffers);+    iterator start_pos = begin + search_position;+    iterator end = iterator::end(data_buffers);++    // Look for a match.+    boost::match_results<iterator,+      typename std::vector<boost::sub_match<iterator> >::allocator_type>+        match_results;+    if (regex_search(start_pos, end, match_results, expr,+          boost::match_default | boost::match_partial))+    {+      if (match_results[0].matched)+      {+        // Full match. We're done.+        ec = asio::error_code();+        return match_results[0].second - begin;+      }+      else+      {+        // Partial match. Next search needs to start from beginning of match.+        search_position = match_results[0].first - begin;+      }+    }+    else+    {+      // No match. Next search can start with the new data.+      search_position = end - begin;+    }++    // Check if buffer is full.+    if (b.size() == b.max_size())+    {+      ec = error::not_found;+      return 0;+    }++    // Need more data.+    std::size_t bytes_to_read = std::min<std::size_t>(+          std::max<std::size_t>(512, b.capacity() - b.size()),+          std::min<std::size_t>(65536, b.max_size() - b.size()));+    std::size_t pos = b.size();+    b.grow(bytes_to_read);+    std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);+    b.shrink(bytes_to_read - bytes_transferred);+    if (ec)+      return 0;+  }+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++template <typename SyncReadStream,+    typename DynamicBuffer_v2, typename MatchCondition>+inline std::size_t read_until(SyncReadStream& s,+    DynamicBuffer_v2 buffers, MatchCondition match_condition,+    typename constraint<+      is_match_condition<MatchCondition>::value+    >::type,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+{+  asio::error_code ec;+  std::size_t bytes_transferred = read_until(s,+      ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+      match_condition, ec);+  asio::detail::throw_error(ec, "read_until");+  return bytes_transferred;+}++template <typename SyncReadStream,+    typename DynamicBuffer_v2, typename MatchCondition>+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,+    MatchCondition match_condition, asio::error_code& ec,+    typename constraint<+      is_match_condition<MatchCondition>::value+    >::type,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+{+  DynamicBuffer_v2& b = buffers;++  std::size_t search_position = 0;+  for (;;)+  {+    // Determine the range of the data to be searched.+    typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;+    typedef buffers_iterator<buffers_type> iterator;+    buffers_type data_buffers =+      const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());+    iterator begin = iterator::begin(data_buffers);+    iterator start_pos = begin + search_position;+    iterator end = iterator::end(data_buffers);++    // Look for a match.+    std::pair<iterator, bool> result = match_condition(start_pos, end);+    if (result.second)+    {+      // Full match. We're done.+      ec = asio::error_code();+      return result.first - begin;+    }+    else if (result.first != end)+    {+      // Partial match. Next search needs to start from beginning of match.+      search_position = result.first - begin;+    }+    else+    {+      // No match. Next search can start with the new data.+      search_position = end - begin;+    }++    // Check if buffer is full.+    if (b.size() == b.max_size())+    {+      ec = error::not_found;+      return 0;+    }++    // Need more data.+    std::size_t bytes_to_read = std::min<std::size_t>(+          std::max<std::size_t>(512, b.capacity() - b.size()),+          std::min<std::size_t>(65536, b.max_size() - b.size()));+    std::size_t pos = b.size();+    b.grow(bytes_to_read);+    std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);+    b.shrink(bytes_to_read - bytes_transferred);+    if (ec)+      return 0;+  }+}++#endif // !defined(ASIO_NO_EXTENSIONS)++#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++namespace detail+{+  template <typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  class read_until_delim_op_v1+    : public base_from_cancellation_state<ReadHandler>+  {+  public:+    template <typename BufferSequence>+    read_until_delim_op_v1(AsyncReadStream& stream,+        ASIO_MOVE_ARG(BufferSequence) buffers,+        char delim, ReadHandler& handler)+      : base_from_cancellation_state<ReadHandler>(+          handler, enable_partial_cancellation()),+        stream_(stream),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+        delim_(delim),+        start_(0),+        search_position_(0),+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+    {+    }++#if defined(ASIO_HAS_MOVE)+    read_until_delim_op_v1(const read_until_delim_op_v1& other)+      : base_from_cancellation_state<ReadHandler>(other),+        stream_(other.stream_),+        buffers_(other.buffers_),+        delim_(other.delim_),+        start_(other.start_),+        search_position_(other.search_position_),+        handler_(other.handler_)+    {+    }++    read_until_delim_op_v1(read_until_delim_op_v1&& other)+      : base_from_cancellation_state<ReadHandler>(+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),+        stream_(other.stream_),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+        delim_(other.delim_),+        start_(other.start_),+        search_position_(other.search_position_),+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+    {+    }+#endif // defined(ASIO_HAS_MOVE)++    void operator()(asio::error_code ec,+        std::size_t bytes_transferred, int start = 0)+    {+      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+      std::size_t bytes_to_read;+      switch (start_ = start)+      {+      case 1:+        for (;;)+        {+          {+            // Determine the range of the data to be searched.+            typedef typename DynamicBuffer_v1::const_buffers_type+              buffers_type;+            typedef buffers_iterator<buffers_type> iterator;+            buffers_type data_buffers = buffers_.data();+            iterator begin = iterator::begin(data_buffers);+            iterator start_pos = begin + search_position_;+            iterator end = iterator::end(data_buffers);++            // Look for a match.+            iterator iter = std::find(start_pos, end, delim_);+            if (iter != end)+            {+              // Found a match. We're done.+              search_position_ = iter - begin + 1;+              bytes_to_read = 0;+            }++            // No match yet. Check if buffer is full.+            else if (buffers_.size() == buffers_.max_size())+            {+              search_position_ = not_found;+              bytes_to_read = 0;+            }++            // Need to read some more data.+            else+            {+              // Next search can start with the new data.+              search_position_ = end - begin;+              bytes_to_read = std::min<std::size_t>(+                    std::max<std::size_t>(512,+                      buffers_.capacity() - buffers_.size()),+                    std::min<std::size_t>(65536,+                      buffers_.max_size() - buffers_.size()));+            }+          }++          // Check if we're done.+          if (!start && bytes_to_read == 0)+            break;++          // Start a new asynchronous read operation to obtain more data.+          {+            ASIO_HANDLER_LOCATION((+                  __FILE__, __LINE__, "async_read_until"));+            stream_.async_read_some(buffers_.prepare(bytes_to_read),+                ASIO_MOVE_CAST(read_until_delim_op_v1)(*this));+          }+          return; default:+          buffers_.commit(bytes_transferred);+          if (ec || bytes_transferred == 0)+            break;+          if (this->cancelled() != cancellation_type::none)+          {+            ec = error::operation_aborted;+            break;+          }+        }++        const asio::error_code result_ec =+          (search_position_ == not_found)+          ? error::not_found : ec;++        const std::size_t result_n =+          (ec || search_position_ == not_found)+          ? 0 : search_position_;++        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+      }+    }++  //private:+    AsyncReadStream& stream_;+    DynamicBuffer_v1 buffers_;+    char delim_;+    int start_;+    std::size_t search_position_;+    ReadHandler handler_;+  };++  template <typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_until_delim_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_until_delim_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline bool asio_handler_is_continuation(+      read_until_delim_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+    return this_handler->start_ == 0 ? true+      : asio_handler_cont_helpers::is_continuation(+          this_handler->handler_);+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_until_delim_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_until_delim_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream>+  class initiate_async_read_until_delim_v1+  {+  public:+    typedef typename AsyncReadStream::executor_type executor_type;++    explicit initiate_async_read_until_delim_v1(AsyncReadStream& stream)+      : stream_(stream)+    {+    }++    executor_type get_executor() const ASIO_NOEXCEPT+    {+      return stream_.get_executor();+    }++    template <typename ReadHandler, typename DynamicBuffer_v1>+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+        char delim) const+    {+      // If you get an error on the following line it means that your handler+      // does not meet the documented type requirements for a ReadHandler.+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++      non_const_lvalue<ReadHandler> handler2(handler);+      read_until_delim_op_v1<AsyncReadStream,+        typename decay<DynamicBuffer_v1>::type,+          typename decay<ReadHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+            delim, handler2.value)(asio::error_code(), 0, 1);+    }++  private:+    AsyncReadStream& stream_;+  };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename AsyncReadStream, typename DynamicBuffer_v1,+    typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+    detail::read_until_delim_op_v1<AsyncReadStream,+      DynamicBuffer_v1, ReadHandler>,+    DefaultCandidate>+  : Associator<ReadHandler, DefaultCandidate>+{+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_until_delim_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>& h) ASIO_NOEXCEPT+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_until_delim_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v1,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    char delim, ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim)))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim);+}++namespace detail+{+  template <typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  class read_until_delim_string_op_v1+    : public base_from_cancellation_state<ReadHandler>+  {+  public:+    template <typename BufferSequence>+    read_until_delim_string_op_v1(AsyncReadStream& stream,+        ASIO_MOVE_ARG(BufferSequence) buffers,+        const std::string& delim, ReadHandler& handler)+      : base_from_cancellation_state<ReadHandler>(+          handler, enable_partial_cancellation()),+        stream_(stream),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+        delim_(delim),+        start_(0),+        search_position_(0),+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+    {+    }++#if defined(ASIO_HAS_MOVE)+    read_until_delim_string_op_v1(const read_until_delim_string_op_v1& other)+      : base_from_cancellation_state<ReadHandler>(other),+        stream_(other.stream_),+        buffers_(other.buffers_),+        delim_(other.delim_),+        start_(other.start_),+        search_position_(other.search_position_),+        handler_(other.handler_)+    {+    }++    read_until_delim_string_op_v1(read_until_delim_string_op_v1&& other)+      : base_from_cancellation_state<ReadHandler>(+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),+        stream_(other.stream_),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+        delim_(ASIO_MOVE_CAST(std::string)(other.delim_)),+        start_(other.start_),+        search_position_(other.search_position_),+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+    {+    }+#endif // defined(ASIO_HAS_MOVE)++    void operator()(asio::error_code ec,+        std::size_t bytes_transferred, int start = 0)+    {+      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+      std::size_t bytes_to_read;+      switch (start_ = start)+      {+      case 1:+        for (;;)+        {+          {+            // Determine the range of the data to be searched.+            typedef typename DynamicBuffer_v1::const_buffers_type+              buffers_type;+            typedef buffers_iterator<buffers_type> iterator;+            buffers_type data_buffers = buffers_.data();+            iterator begin = iterator::begin(data_buffers);+            iterator start_pos = begin + search_position_;+            iterator end = iterator::end(data_buffers);++            // Look for a match.+            std::pair<iterator, bool> result = detail::partial_search(+                start_pos, end, delim_.begin(), delim_.end());+            if (result.first != end && result.second)+            {+              // Full match. We're done.+              search_position_ = result.first - begin + delim_.length();+              bytes_to_read = 0;+            }++            // No match yet. Check if buffer is full.+            else if (buffers_.size() == buffers_.max_size())+            {+              search_position_ = not_found;+              bytes_to_read = 0;+            }++            // Need to read some more data.+            else+            {+              if (result.first != end)+              {+                // Partial match. Next search needs to start from beginning of+                // match.+                search_position_ = result.first - begin;+              }+              else+              {+                // Next search can start with the new data.+                search_position_ = end - begin;+              }++              bytes_to_read = std::min<std::size_t>(+                    std::max<std::size_t>(512,+                      buffers_.capacity() - buffers_.size()),+                    std::min<std::size_t>(65536,+                      buffers_.max_size() - buffers_.size()));+            }+          }++          // Check if we're done.+          if (!start && bytes_to_read == 0)+            break;++          // Start a new asynchronous read operation to obtain more data.+          {+            ASIO_HANDLER_LOCATION((+                  __FILE__, __LINE__, "async_read_until"));+            stream_.async_read_some(buffers_.prepare(bytes_to_read),+                ASIO_MOVE_CAST(read_until_delim_string_op_v1)(*this));+          }+          return; default:+          buffers_.commit(bytes_transferred);+          if (ec || bytes_transferred == 0)+            break;+          if (this->cancelled() != cancellation_type::none)+          {+            ec = error::operation_aborted;+            break;+          }+        }++        const asio::error_code result_ec =+          (search_position_ == not_found)+          ? error::not_found : ec;++        const std::size_t result_n =+          (ec || search_position_ == not_found)+          ? 0 : search_position_;++        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+      }+    }++  //private:+    AsyncReadStream& stream_;+    DynamicBuffer_v1 buffers_;+    std::string delim_;+    int start_;+    std::size_t search_position_;+    ReadHandler handler_;+  };++  template <typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_until_delim_string_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_until_delim_string_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline bool asio_handler_is_continuation(+      read_until_delim_string_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+    return this_handler->start_ == 0 ? true+      : asio_handler_cont_helpers::is_continuation(+          this_handler->handler_);+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_until_delim_string_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_until_delim_string_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream>+  class initiate_async_read_until_delim_string_v1+  {+  public:+    typedef typename AsyncReadStream::executor_type executor_type;++    explicit initiate_async_read_until_delim_string_v1(AsyncReadStream& stream)+      : stream_(stream)+    {+    }++    executor_type get_executor() const ASIO_NOEXCEPT+    {+      return stream_.get_executor();+    }++    template <typename ReadHandler, typename DynamicBuffer_v1>+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+        const std::string& delim) const+    {+      // If you get an error on the following line it means that your handler+      // does not meet the documented type requirements for a ReadHandler.+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++      non_const_lvalue<ReadHandler> handler2(handler);+      read_until_delim_string_op_v1<AsyncReadStream,+        typename decay<DynamicBuffer_v1>::type,+          typename decay<ReadHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+            delim, handler2.value)(asio::error_code(), 0, 1);+    }++  private:+    AsyncReadStream& stream_;+  };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename AsyncReadStream, typename DynamicBuffer_v1,+    typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+    detail::read_until_delim_string_op_v1<AsyncReadStream,+      DynamicBuffer_v1, ReadHandler>,+    DefaultCandidate>+  : Associator<ReadHandler, DefaultCandidate>+{+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_until_delim_string_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>& h) ASIO_NOEXCEPT+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_until_delim_string_op_v1<AsyncReadStream,+        DynamicBuffer_v1, ReadHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v1,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    ASIO_STRING_VIEW_PARAM delim,+    ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_until_delim_string_v1<+          AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        static_cast<std::string>(delim))))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+      static_cast<std::string>(delim));+}++#if !defined(ASIO_NO_EXTENSIONS)+#if defined(ASIO_HAS_BOOST_REGEX)++namespace detail+{+  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename RegEx, typename ReadHandler>+  class read_until_expr_op_v1+    : public base_from_cancellation_state<ReadHandler>+  {+  public:+    template <typename BufferSequence>+    read_until_expr_op_v1(AsyncReadStream& stream,+        ASIO_MOVE_ARG(BufferSequence) buffers,+        const boost::regex& expr, ReadHandler& handler)+      : base_from_cancellation_state<ReadHandler>(+          handler, enable_partial_cancellation()),+        stream_(stream),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+        expr_(expr),+        start_(0),+        search_position_(0),+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+    {+    }++#if defined(ASIO_HAS_MOVE)+    read_until_expr_op_v1(const read_until_expr_op_v1& other)+      : base_from_cancellation_state<ReadHandler>(other),+        stream_(other.stream_),+        buffers_(other.buffers_),+        expr_(other.expr_),+        start_(other.start_),+        search_position_(other.search_position_),+        handler_(other.handler_)+    {+    }++    read_until_expr_op_v1(read_until_expr_op_v1&& other)+      : base_from_cancellation_state<ReadHandler>(+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),+        stream_(other.stream_),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+        expr_(other.expr_),+        start_(other.start_),+        search_position_(other.search_position_),+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+    {+    }+#endif // defined(ASIO_HAS_MOVE)++    void operator()(asio::error_code ec,+        std::size_t bytes_transferred, int start = 0)+    {+      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+      std::size_t bytes_to_read;+      switch (start_ = start)+      {+      case 1:+        for (;;)+        {+          {+            // Determine the range of the data to be searched.+            typedef typename DynamicBuffer_v1::const_buffers_type+              buffers_type;+            typedef buffers_iterator<buffers_type> iterator;+            buffers_type data_buffers = buffers_.data();+            iterator begin = iterator::begin(data_buffers);+            iterator start_pos = begin + search_position_;+            iterator end = iterator::end(data_buffers);++            // Look for a match.+            boost::match_results<iterator,+              typename std::vector<boost::sub_match<iterator> >::allocator_type>+                match_results;+            bool match = regex_search(start_pos, end, match_results, expr_,+                boost::match_default | boost::match_partial);+            if (match && match_results[0].matched)+            {+              // Full match. We're done.+              search_position_ = match_results[0].second - begin;+              bytes_to_read = 0;+            }++            // No match yet. Check if buffer is full.+            else if (buffers_.size() == buffers_.max_size())+            {+              search_position_ = not_found;+              bytes_to_read = 0;+            }++            // Need to read some more data.+            else+            {+              if (match)+              {+                // Partial match. Next search needs to start from beginning of+                // match.+                search_position_ = match_results[0].first - begin;+              }+              else+              {+                // Next search can start with the new data.+                search_position_ = end - begin;+              }++              bytes_to_read = std::min<std::size_t>(+                    std::max<std::size_t>(512,+                      buffers_.capacity() - buffers_.size()),+                    std::min<std::size_t>(65536,+                      buffers_.max_size() - buffers_.size()));+            }+          }++          // Check if we're done.+          if (!start && bytes_to_read == 0)+            break;++          // Start a new asynchronous read operation to obtain more data.+          {+            ASIO_HANDLER_LOCATION((+                  __FILE__, __LINE__, "async_read_until"));+            stream_.async_read_some(buffers_.prepare(bytes_to_read),+                ASIO_MOVE_CAST(read_until_expr_op_v1)(*this));+          }+          return; default:+          buffers_.commit(bytes_transferred);+          if (ec || bytes_transferred == 0)+            break;+          if (this->cancelled() != cancellation_type::none)+          {+            ec = error::operation_aborted;+            break;+          }+        }++        const asio::error_code result_ec =+          (search_position_ == not_found)+          ? error::not_found : ec;++        const std::size_t result_n =+          (ec || search_position_ == not_found)+          ? 0 : search_position_;++        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+      }+    }++  //private:+    AsyncReadStream& stream_;+    DynamicBuffer_v1 buffers_;+    RegEx expr_;+    int start_;+    std::size_t search_position_;+    ReadHandler handler_;+  };++  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename RegEx, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_until_expr_op_v1<AsyncReadStream,+        DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename RegEx, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_until_expr_op_v1<AsyncReadStream,+        DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename RegEx, typename ReadHandler>+  inline bool asio_handler_is_continuation(+      read_until_expr_op_v1<AsyncReadStream,+        DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+  {+    return this_handler->start_ == 0 ? true+      : asio_handler_cont_helpers::is_continuation(+          this_handler->handler_);+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename RegEx, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_until_expr_op_v1<AsyncReadStream,+        DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename RegEx, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_until_expr_op_v1<AsyncReadStream,+        DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream>+  class initiate_async_read_until_expr_v1+  {+  public:+    typedef typename AsyncReadStream::executor_type executor_type;++    explicit initiate_async_read_until_expr_v1(AsyncReadStream& stream)+      : stream_(stream)+    {+    }++    executor_type get_executor() const ASIO_NOEXCEPT+    {+      return stream_.get_executor();+    }++    template <typename ReadHandler, typename DynamicBuffer_v1, typename RegEx>+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, const RegEx& expr) const+    {+      // If you get an error on the following line it means that your handler+      // does not meet the documented type requirements for a ReadHandler.+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++      non_const_lvalue<ReadHandler> handler2(handler);+      read_until_expr_op_v1<AsyncReadStream,+        typename decay<DynamicBuffer_v1>::type,+          RegEx, typename decay<ReadHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+            expr, handler2.value)(asio::error_code(), 0, 1);+    }++  private:+    AsyncReadStream& stream_;+  };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename AsyncReadStream, typename DynamicBuffer_v1,+    typename RegEx, typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+    detail::read_until_expr_op_v1<AsyncReadStream,+      DynamicBuffer_v1, RegEx, ReadHandler>,+    DefaultCandidate>+  : Associator<ReadHandler, DefaultCandidate>+{+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_until_expr_op_v1<AsyncReadStream,+        DynamicBuffer_v1, RegEx, ReadHandler>& h) ASIO_NOEXCEPT+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_until_expr_op_v1<AsyncReadStream,+        DynamicBuffer_v1, RegEx, ReadHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v1,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    const boost::regex& expr,+    ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr)))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr);+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++namespace detail+{+  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename MatchCondition, typename ReadHandler>+  class read_until_match_op_v1+    : public base_from_cancellation_state<ReadHandler>+  {+  public:+    template <typename BufferSequence>+    read_until_match_op_v1(AsyncReadStream& stream,+        ASIO_MOVE_ARG(BufferSequence) buffers,+        MatchCondition match_condition, ReadHandler& handler)+      : base_from_cancellation_state<ReadHandler>(+          handler, enable_partial_cancellation()),+        stream_(stream),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+        match_condition_(match_condition),+        start_(0),+        search_position_(0),+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+    {+    }++#if defined(ASIO_HAS_MOVE)+    read_until_match_op_v1(const read_until_match_op_v1& other)+      : base_from_cancellation_state<ReadHandler>(other),+        stream_(other.stream_),+        buffers_(other.buffers_),+        match_condition_(other.match_condition_),+        start_(other.start_),+        search_position_(other.search_position_),+        handler_(other.handler_)+    {+    }++    read_until_match_op_v1(read_until_match_op_v1&& other)+      : base_from_cancellation_state<ReadHandler>(+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),+        stream_(other.stream_),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),+        match_condition_(other.match_condition_),+        start_(other.start_),+        search_position_(other.search_position_),+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+    {+    }+#endif // defined(ASIO_HAS_MOVE)++    void operator()(asio::error_code ec,+        std::size_t bytes_transferred, int start = 0)+    {+      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+      std::size_t bytes_to_read;+      switch (start_ = start)+      {+      case 1:+        for (;;)+        {+          {+            // Determine the range of the data to be searched.+            typedef typename DynamicBuffer_v1::const_buffers_type+              buffers_type;+            typedef buffers_iterator<buffers_type> iterator;+            buffers_type data_buffers = buffers_.data();+            iterator begin = iterator::begin(data_buffers);+            iterator start_pos = begin + search_position_;+            iterator end = iterator::end(data_buffers);++            // Look for a match.+            std::pair<iterator, bool> result = match_condition_(start_pos, end);+            if (result.second)+            {+              // Full match. We're done.+              search_position_ = result.first - begin;+              bytes_to_read = 0;+            }++            // No match yet. Check if buffer is full.+            else if (buffers_.size() == buffers_.max_size())+            {+              search_position_ = not_found;+              bytes_to_read = 0;+            }++            // Need to read some more data.+            else+            {+              if (result.first != end)+              {+                // Partial match. Next search needs to start from beginning of+                // match.+                search_position_ = result.first - begin;+              }+              else+              {+                // Next search can start with the new data.+                search_position_ = end - begin;+              }++              bytes_to_read = std::min<std::size_t>(+                    std::max<std::size_t>(512,+                      buffers_.capacity() - buffers_.size()),+                    std::min<std::size_t>(65536,+                      buffers_.max_size() - buffers_.size()));+            }+          }++          // Check if we're done.+          if (!start && bytes_to_read == 0)+            break;++          // Start a new asynchronous read operation to obtain more data.+          {+            ASIO_HANDLER_LOCATION((+                  __FILE__, __LINE__, "async_read_until"));+            stream_.async_read_some(buffers_.prepare(bytes_to_read),+                ASIO_MOVE_CAST(read_until_match_op_v1)(*this));+          }+          return; default:+          buffers_.commit(bytes_transferred);+          if (ec || bytes_transferred == 0)+            break;+          if (this->cancelled() != cancellation_type::none)+          {+            ec = error::operation_aborted;+            break;+          }+        }++        const asio::error_code result_ec =+          (search_position_ == not_found)+          ? error::not_found : ec;++        const std::size_t result_n =+          (ec || search_position_ == not_found)+          ? 0 : search_position_;++        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+      }+    }++  //private:+    AsyncReadStream& stream_;+    DynamicBuffer_v1 buffers_;+    MatchCondition match_condition_;+    int start_;+    std::size_t search_position_;+    ReadHandler handler_;+  };++  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename MatchCondition, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+        MatchCondition, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename MatchCondition, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+        MatchCondition, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v1,+      typename MatchCondition, typename ReadHandler>+  inline bool asio_handler_is_continuation(+      read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+        MatchCondition, ReadHandler>* this_handler)+  {+    return this_handler->start_ == 0 ? true+      : asio_handler_cont_helpers::is_continuation(+          this_handler->handler_);+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename MatchCondition,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+        MatchCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v1, typename MatchCondition,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,+      MatchCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream>+  class initiate_async_read_until_match_v1+  {+  public:+    typedef typename AsyncReadStream::executor_type executor_type;++    explicit initiate_async_read_until_match_v1(AsyncReadStream& stream)+      : stream_(stream)+    {+    }++    executor_type get_executor() const ASIO_NOEXCEPT+    {+      return stream_.get_executor();+    }++    template <typename ReadHandler,+        typename DynamicBuffer_v1, typename MatchCondition>+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+        MatchCondition match_condition) const+    {+      // If you get an error on the following line it means that your handler+      // does not meet the documented type requirements for a ReadHandler.+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++      non_const_lvalue<ReadHandler> handler2(handler);+      read_until_match_op_v1<AsyncReadStream,+        typename decay<DynamicBuffer_v1>::type,+          MatchCondition, typename decay<ReadHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+            match_condition, handler2.value)(asio::error_code(), 0, 1);+    }++  private:+    AsyncReadStream& stream_;+  };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename AsyncReadStream, typename DynamicBuffer_v1,+    typename MatchCondition, typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+    detail::read_until_match_op_v1<AsyncReadStream,+      DynamicBuffer_v1, MatchCondition, ReadHandler>,+    DefaultCandidate>+  : Associator<ReadHandler, DefaultCandidate>+{+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_until_match_op_v1<AsyncReadStream,+        DynamicBuffer_v1, MatchCondition, ReadHandler>& h) ASIO_NOEXCEPT+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_until_match_op_v1<AsyncReadStream,+        DynamicBuffer_v1, MatchCondition, ReadHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream,+    typename DynamicBuffer_v1, typename MatchCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    MatchCondition match_condition, ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_match_condition<MatchCondition>::value+    >::type,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_until_match_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        match_condition)))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_until_match_v1<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+      match_condition);+}++#if !defined(ASIO_NO_IOSTREAM)++template <typename AsyncReadStream, typename Allocator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    asio::basic_streambuf<Allocator>& b,+    char delim, ASIO_MOVE_ARG(ReadToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read_until(s, basic_streambuf_ref<Allocator>(b),+        delim, ASIO_MOVE_CAST(ReadToken)(token))))+{+  return async_read_until(s, basic_streambuf_ref<Allocator>(b),+      delim, ASIO_MOVE_CAST(ReadToken)(token));+}++template <typename AsyncReadStream, typename Allocator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    asio::basic_streambuf<Allocator>& b,+    ASIO_STRING_VIEW_PARAM delim,+    ASIO_MOVE_ARG(ReadToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read_until(s, basic_streambuf_ref<Allocator>(b),+        delim, ASIO_MOVE_CAST(ReadToken)(token))))+{+  return async_read_until(s, basic_streambuf_ref<Allocator>(b),+      delim, ASIO_MOVE_CAST(ReadToken)(token));+}++#if defined(ASIO_HAS_BOOST_REGEX)++template <typename AsyncReadStream, typename Allocator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    asio::basic_streambuf<Allocator>& b, const boost::regex& expr,+    ASIO_MOVE_ARG(ReadToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read_until(s, basic_streambuf_ref<Allocator>(b),+        expr, ASIO_MOVE_CAST(ReadToken)(token))))+{+  return async_read_until(s, basic_streambuf_ref<Allocator>(b),+      expr, ASIO_MOVE_CAST(ReadToken)(token));+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++template <typename AsyncReadStream, typename Allocator, typename MatchCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    asio::basic_streambuf<Allocator>& b,+    MatchCondition match_condition, ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<is_match_condition<MatchCondition>::value>::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read_until(s, basic_streambuf_ref<Allocator>(b),+        match_condition, ASIO_MOVE_CAST(ReadToken)(token))))+{+  return async_read_until(s, basic_streambuf_ref<Allocator>(b),+      match_condition, ASIO_MOVE_CAST(ReadToken)(token));+}++#endif // !defined(ASIO_NO_IOSTREAM)+#endif // !defined(ASIO_NO_EXTENSIONS)+#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)++namespace detail+{+  template <typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  class read_until_delim_op_v2+    : public base_from_cancellation_state<ReadHandler>+  {+  public:+    template <typename BufferSequence>+    read_until_delim_op_v2(AsyncReadStream& stream,+        ASIO_MOVE_ARG(BufferSequence) buffers,+        char delim, ReadHandler& handler)+      : base_from_cancellation_state<ReadHandler>(+          handler, enable_partial_cancellation()),+        stream_(stream),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+        delim_(delim),+        start_(0),+        search_position_(0),+        bytes_to_read_(0),+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+    {+    }++#if defined(ASIO_HAS_MOVE)+    read_until_delim_op_v2(const read_until_delim_op_v2& other)+      : base_from_cancellation_state<ReadHandler>(other),+        stream_(other.stream_),+        buffers_(other.buffers_),+        delim_(other.delim_),+        start_(other.start_),+        search_position_(other.search_position_),+        bytes_to_read_(other.bytes_to_read_),+        handler_(other.handler_)+    {+    }++    read_until_delim_op_v2(read_until_delim_op_v2&& other)+      : base_from_cancellation_state<ReadHandler>(+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),+        stream_(other.stream_),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+        delim_(other.delim_),+        start_(other.start_),+        search_position_(other.search_position_),+        bytes_to_read_(other.bytes_to_read_),+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+    {+    }+#endif // defined(ASIO_HAS_MOVE)++    void operator()(asio::error_code ec,+        std::size_t bytes_transferred, int start = 0)+    {+      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+      std::size_t pos;+      switch (start_ = start)+      {+      case 1:+        for (;;)+        {+          {+            // Determine the range of the data to be searched.+            typedef typename DynamicBuffer_v2::const_buffers_type+              buffers_type;+            typedef buffers_iterator<buffers_type> iterator;+            buffers_type data_buffers =+              const_cast<const DynamicBuffer_v2&>(buffers_).data(+                  0, buffers_.size());+            iterator begin = iterator::begin(data_buffers);+            iterator start_pos = begin + search_position_;+            iterator end = iterator::end(data_buffers);++            // Look for a match.+            iterator iter = std::find(start_pos, end, delim_);+            if (iter != end)+            {+              // Found a match. We're done.+              search_position_ = iter - begin + 1;+              bytes_to_read_ = 0;+            }++            // No match yet. Check if buffer is full.+            else if (buffers_.size() == buffers_.max_size())+            {+              search_position_ = not_found;+              bytes_to_read_ = 0;+            }++            // Need to read some more data.+            else+            {+              // Next search can start with the new data.+              search_position_ = end - begin;+              bytes_to_read_ = std::min<std::size_t>(+                    std::max<std::size_t>(512,+                      buffers_.capacity() - buffers_.size()),+                    std::min<std::size_t>(65536,+                      buffers_.max_size() - buffers_.size()));+            }+          }++          // Check if we're done.+          if (!start && bytes_to_read_ == 0)+            break;++          // Start a new asynchronous read operation to obtain more data.+          pos = buffers_.size();+          buffers_.grow(bytes_to_read_);+          {+            ASIO_HANDLER_LOCATION((+                  __FILE__, __LINE__, "async_read_until"));+            stream_.async_read_some(buffers_.data(pos, bytes_to_read_),+                ASIO_MOVE_CAST(read_until_delim_op_v2)(*this));+          }+          return; default:+          buffers_.shrink(bytes_to_read_ - bytes_transferred);+          if (ec || bytes_transferred == 0)+            break;+          if (this->cancelled() != cancellation_type::none)+          {+            ec = error::operation_aborted;+            break;+          }+        }++        const asio::error_code result_ec =+          (search_position_ == not_found)+          ? error::not_found : ec;++        const std::size_t result_n =+          (ec || search_position_ == not_found)+          ? 0 : search_position_;++        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+      }+    }++  //private:+    AsyncReadStream& stream_;+    DynamicBuffer_v2 buffers_;+    char delim_;+    int start_;+    std::size_t search_position_;+    std::size_t bytes_to_read_;+    ReadHandler handler_;+  };++  template <typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_until_delim_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_until_delim_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline bool asio_handler_is_continuation(+      read_until_delim_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+    return this_handler->start_ == 0 ? true+      : asio_handler_cont_helpers::is_continuation(+          this_handler->handler_);+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_until_delim_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_until_delim_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream>+  class initiate_async_read_until_delim_v2+  {+  public:+    typedef typename AsyncReadStream::executor_type executor_type;++    explicit initiate_async_read_until_delim_v2(AsyncReadStream& stream)+      : stream_(stream)+    {+    }++    executor_type get_executor() const ASIO_NOEXCEPT+    {+      return stream_.get_executor();+    }++    template <typename ReadHandler, typename DynamicBuffer_v2>+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v2) buffers, char delim) const+    {+      // If you get an error on the following line it means that your handler+      // does not meet the documented type requirements for a ReadHandler.+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++      non_const_lvalue<ReadHandler> handler2(handler);+      read_until_delim_op_v2<AsyncReadStream,+        typename decay<DynamicBuffer_v2>::type,+          typename decay<ReadHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+            delim, handler2.value)(asio::error_code(), 0, 1);+    }++  private:+    AsyncReadStream& stream_;+  };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename AsyncReadStream, typename DynamicBuffer_v2,+    typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+    detail::read_until_delim_op_v2<AsyncReadStream,+      DynamicBuffer_v2, ReadHandler>,+    DefaultCandidate>+  : Associator<ReadHandler, DefaultCandidate>+{+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_until_delim_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>& h) ASIO_NOEXCEPT+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_until_delim_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v2,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+    char delim, ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_until_delim_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim)))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_until_delim_v2<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim);+}++namespace detail+{+  template <typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  class read_until_delim_string_op_v2+    : public base_from_cancellation_state<ReadHandler>+  {+  public:+    template <typename BufferSequence>+    read_until_delim_string_op_v2(AsyncReadStream& stream,+        ASIO_MOVE_ARG(BufferSequence) buffers,+        const std::string& delim, ReadHandler& handler)+      : base_from_cancellation_state<ReadHandler>(+          handler, enable_partial_cancellation()),+        stream_(stream),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+        delim_(delim),+        start_(0),+        search_position_(0),+        bytes_to_read_(0),+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+    {+    }++#if defined(ASIO_HAS_MOVE)+    read_until_delim_string_op_v2(const read_until_delim_string_op_v2& other)+      : base_from_cancellation_state<ReadHandler>(other),+        stream_(other.stream_),+        buffers_(other.buffers_),+        delim_(other.delim_),+        start_(other.start_),+        search_position_(other.search_position_),+        bytes_to_read_(other.bytes_to_read_),+        handler_(other.handler_)+    {+    }++    read_until_delim_string_op_v2(read_until_delim_string_op_v2&& other)+      : base_from_cancellation_state<ReadHandler>(+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),+        stream_(other.stream_),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+        delim_(ASIO_MOVE_CAST(std::string)(other.delim_)),+        start_(other.start_),+        search_position_(other.search_position_),+        bytes_to_read_(other.bytes_to_read_),+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+    {+    }+#endif // defined(ASIO_HAS_MOVE)++    void operator()(asio::error_code ec,+        std::size_t bytes_transferred, int start = 0)+    {+      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+      std::size_t pos;+      switch (start_ = start)+      {+      case 1:+        for (;;)+        {+          {+            // Determine the range of the data to be searched.+            typedef typename DynamicBuffer_v2::const_buffers_type+              buffers_type;+            typedef buffers_iterator<buffers_type> iterator;+            buffers_type data_buffers =+              const_cast<const DynamicBuffer_v2&>(buffers_).data(+                  0, buffers_.size());+            iterator begin = iterator::begin(data_buffers);+            iterator start_pos = begin + search_position_;+            iterator end = iterator::end(data_buffers);++            // Look for a match.+            std::pair<iterator, bool> result = detail::partial_search(+                start_pos, end, delim_.begin(), delim_.end());+            if (result.first != end && result.second)+            {+              // Full match. We're done.+              search_position_ = result.first - begin + delim_.length();+              bytes_to_read_ = 0;+            }++            // No match yet. Check if buffer is full.+            else if (buffers_.size() == buffers_.max_size())+            {+              search_position_ = not_found;+              bytes_to_read_ = 0;+            }++            // Need to read some more data.+            else+            {+              if (result.first != end)+              {+                // Partial match. Next search needs to start from beginning of+                // match.+                search_position_ = result.first - begin;+              }+              else+              {+                // Next search can start with the new data.+                search_position_ = end - begin;+              }++              bytes_to_read_ = std::min<std::size_t>(+                    std::max<std::size_t>(512,+                      buffers_.capacity() - buffers_.size()),+                    std::min<std::size_t>(65536,+                      buffers_.max_size() - buffers_.size()));+            }+          }++          // Check if we're done.+          if (!start && bytes_to_read_ == 0)+            break;++          // Start a new asynchronous read operation to obtain more data.+          pos = buffers_.size();+          buffers_.grow(bytes_to_read_);+          {+            ASIO_HANDLER_LOCATION((+                  __FILE__, __LINE__, "async_read_until"));+            stream_.async_read_some(buffers_.data(pos, bytes_to_read_),+                ASIO_MOVE_CAST(read_until_delim_string_op_v2)(*this));+          }+          return; default:+          buffers_.shrink(bytes_to_read_ - bytes_transferred);+          if (ec || bytes_transferred == 0)+            break;+          if (this->cancelled() != cancellation_type::none)+          {+            ec = error::operation_aborted;+            break;+          }+        }++        const asio::error_code result_ec =+          (search_position_ == not_found)+          ? error::not_found : ec;++        const std::size_t result_n =+          (ec || search_position_ == not_found)+          ? 0 : search_position_;++        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+      }+    }++  //private:+    AsyncReadStream& stream_;+    DynamicBuffer_v2 buffers_;+    std::string delim_;+    int start_;+    std::size_t search_position_;+    std::size_t bytes_to_read_;+    ReadHandler handler_;+  };++  template <typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_until_delim_string_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_until_delim_string_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline bool asio_handler_is_continuation(+      read_until_delim_string_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+    return this_handler->start_ == 0 ? true+      : asio_handler_cont_helpers::is_continuation(+          this_handler->handler_);+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_until_delim_string_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_until_delim_string_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream>+  class initiate_async_read_until_delim_string_v2+  {+  public:+    typedef typename AsyncReadStream::executor_type executor_type;++    explicit initiate_async_read_until_delim_string_v2(AsyncReadStream& stream)+      : stream_(stream)+    {+    }++    executor_type get_executor() const ASIO_NOEXCEPT+    {+      return stream_.get_executor();+    }++    template <typename ReadHandler, typename DynamicBuffer_v2>+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+        const std::string& delim) const+    {+      // If you get an error on the following line it means that your handler+      // does not meet the documented type requirements for a ReadHandler.+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++      non_const_lvalue<ReadHandler> handler2(handler);+      read_until_delim_string_op_v2<AsyncReadStream,+        typename decay<DynamicBuffer_v2>::type,+          typename decay<ReadHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+            delim, handler2.value)(asio::error_code(), 0, 1);+    }++  private:+    AsyncReadStream& stream_;+  };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename AsyncReadStream, typename DynamicBuffer_v2,+    typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+    detail::read_until_delim_string_op_v2<AsyncReadStream,+      DynamicBuffer_v2, ReadHandler>,+    DefaultCandidate>+  : Associator<ReadHandler, DefaultCandidate>+{+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_until_delim_string_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>& h) ASIO_NOEXCEPT+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_until_delim_string_op_v2<AsyncReadStream,+        DynamicBuffer_v2, ReadHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream,+    typename DynamicBuffer_v2,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    DynamicBuffer_v2 buffers, ASIO_STRING_VIEW_PARAM delim,+    ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_until_delim_string_v2<+          AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        static_cast<std::string>(delim))))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_until_delim_string_v2<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+      static_cast<std::string>(delim));+}++#if !defined(ASIO_NO_EXTENSIONS)+#if defined(ASIO_HAS_BOOST_REGEX)++namespace detail+{+  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename RegEx, typename ReadHandler>+  class read_until_expr_op_v2+    : public base_from_cancellation_state<ReadHandler>+  {+  public:+    template <typename BufferSequence>+    read_until_expr_op_v2(AsyncReadStream& stream,+        ASIO_MOVE_ARG(BufferSequence) buffers,+        const boost::regex& expr, ReadHandler& handler)+      : base_from_cancellation_state<ReadHandler>(+          handler, enable_partial_cancellation()),+        stream_(stream),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+        expr_(expr),+        start_(0),+        search_position_(0),+        bytes_to_read_(0),+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+    {+    }++#if defined(ASIO_HAS_MOVE)+    read_until_expr_op_v2(const read_until_expr_op_v2& other)+      : base_from_cancellation_state<ReadHandler>(other),+        stream_(other.stream_),+        buffers_(other.buffers_),+        expr_(other.expr_),+        start_(other.start_),+        search_position_(other.search_position_),+        bytes_to_read_(other.bytes_to_read_),+        handler_(other.handler_)+    {+    }++    read_until_expr_op_v2(read_until_expr_op_v2&& other)+      : base_from_cancellation_state<ReadHandler>(+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),+        stream_(other.stream_),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+        expr_(other.expr_),+        start_(other.start_),+        search_position_(other.search_position_),+        bytes_to_read_(other.bytes_to_read_),+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+    {+    }+#endif // defined(ASIO_HAS_MOVE)++    void operator()(asio::error_code ec,+        std::size_t bytes_transferred, int start = 0)+    {+      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+      std::size_t pos;+      switch (start_ = start)+      {+      case 1:+        for (;;)+        {+          {+            // Determine the range of the data to be searched.+            typedef typename DynamicBuffer_v2::const_buffers_type+              buffers_type;+            typedef buffers_iterator<buffers_type> iterator;+            buffers_type data_buffers =+              const_cast<const DynamicBuffer_v2&>(buffers_).data(+                  0, buffers_.size());+            iterator begin = iterator::begin(data_buffers);+            iterator start_pos = begin + search_position_;+            iterator end = iterator::end(data_buffers);++            // Look for a match.+            boost::match_results<iterator,+              typename std::vector<boost::sub_match<iterator> >::allocator_type>+                match_results;+            bool match = regex_search(start_pos, end, match_results, expr_,+                boost::match_default | boost::match_partial);+            if (match && match_results[0].matched)+            {+              // Full match. We're done.+              search_position_ = match_results[0].second - begin;+              bytes_to_read_ = 0;+            }++            // No match yet. Check if buffer is full.+            else if (buffers_.size() == buffers_.max_size())+            {+              search_position_ = not_found;+              bytes_to_read_ = 0;+            }++            // Need to read some more data.+            else+            {+              if (match)+              {+                // Partial match. Next search needs to start from beginning of+                // match.+                search_position_ = match_results[0].first - begin;+              }+              else+              {+                // Next search can start with the new data.+                search_position_ = end - begin;+              }++              bytes_to_read_ = std::min<std::size_t>(+                    std::max<std::size_t>(512,+                      buffers_.capacity() - buffers_.size()),+                    std::min<std::size_t>(65536,+                      buffers_.max_size() - buffers_.size()));+            }+          }++          // Check if we're done.+          if (!start && bytes_to_read_ == 0)+            break;++          // Start a new asynchronous read operation to obtain more data.+          pos = buffers_.size();+          buffers_.grow(bytes_to_read_);+          {+            ASIO_HANDLER_LOCATION((+                  __FILE__, __LINE__, "async_read_until"));+            stream_.async_read_some(buffers_.data(pos, bytes_to_read_),+                ASIO_MOVE_CAST(read_until_expr_op_v2)(*this));+          }+          return; default:+          buffers_.shrink(bytes_to_read_ - bytes_transferred);+          if (ec || bytes_transferred == 0)+            break;+          if (this->cancelled() != cancellation_type::none)+          {+            ec = error::operation_aborted;+            break;+          }+        }++        const asio::error_code result_ec =+          (search_position_ == not_found)+          ? error::not_found : ec;++        const std::size_t result_n =+          (ec || search_position_ == not_found)+          ? 0 : search_position_;++        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+      }+    }++  //private:+    AsyncReadStream& stream_;+    DynamicBuffer_v2 buffers_;+    RegEx expr_;+    int start_;+    std::size_t search_position_;+    std::size_t bytes_to_read_;+    ReadHandler handler_;+  };++  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename RegEx, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_until_expr_op_v2<AsyncReadStream,+        DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename RegEx, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_until_expr_op_v2<AsyncReadStream,+        DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename RegEx, typename ReadHandler>+  inline bool asio_handler_is_continuation(+      read_until_expr_op_v2<AsyncReadStream,+        DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+  {+    return this_handler->start_ == 0 ? true+      : asio_handler_cont_helpers::is_continuation(+          this_handler->handler_);+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename RegEx, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_until_expr_op_v2<AsyncReadStream,+        DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename RegEx, typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_until_expr_op_v2<AsyncReadStream,+        DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream>+  class initiate_async_read_until_expr_v2+  {+  public:+    typedef typename AsyncReadStream::executor_type executor_type;++    explicit initiate_async_read_until_expr_v2(AsyncReadStream& stream)+      : stream_(stream)+    {+    }++    executor_type get_executor() const ASIO_NOEXCEPT+    {+      return stream_.get_executor();+    }++    template <typename ReadHandler, typename DynamicBuffer_v2, typename RegEx>+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+        const RegEx& expr) const+    {+      // If you get an error on the following line it means that your handler+      // does not meet the documented type requirements for a ReadHandler.+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++      non_const_lvalue<ReadHandler> handler2(handler);+      read_until_expr_op_v2<AsyncReadStream,+        typename decay<DynamicBuffer_v2>::type,+          RegEx, typename decay<ReadHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+            expr, handler2.value)(asio::error_code(), 0, 1);+    }++  private:+    AsyncReadStream& stream_;+  };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename AsyncReadStream, typename DynamicBuffer_v2,+    typename RegEx, typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+    detail::read_until_expr_op_v2<AsyncReadStream,+      DynamicBuffer_v2, RegEx, ReadHandler>,+    DefaultCandidate>+  : Associator<ReadHandler, DefaultCandidate>+{+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_until_expr_op_v2<AsyncReadStream,+        DynamicBuffer_v2, RegEx, ReadHandler>& h) ASIO_NOEXCEPT+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_until_expr_op_v2<AsyncReadStream,+        DynamicBuffer_v2, RegEx, ReadHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream, typename DynamicBuffer_v2,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+    const boost::regex& expr, ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_until_expr_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr)))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_until_expr_v2<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr);+}++#endif // defined(ASIO_HAS_BOOST_REGEX)++namespace detail+{+  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename MatchCondition, typename ReadHandler>+  class read_until_match_op_v2+    : public base_from_cancellation_state<ReadHandler>+  {+  public:+    template <typename BufferSequence>+    read_until_match_op_v2(AsyncReadStream& stream,+        ASIO_MOVE_ARG(BufferSequence) buffers,+        MatchCondition match_condition, ReadHandler& handler)+      : base_from_cancellation_state<ReadHandler>(+          handler, enable_partial_cancellation()),+        stream_(stream),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),+        match_condition_(match_condition),+        start_(0),+        search_position_(0),+        bytes_to_read_(0),+        handler_(ASIO_MOVE_CAST(ReadHandler)(handler))+    {+    }++#if defined(ASIO_HAS_MOVE)+    read_until_match_op_v2(const read_until_match_op_v2& other)+      : base_from_cancellation_state<ReadHandler>(other),+        stream_(other.stream_),+        buffers_(other.buffers_),+        match_condition_(other.match_condition_),+        start_(other.start_),+        search_position_(other.search_position_),+        bytes_to_read_(other.bytes_to_read_),+        handler_(other.handler_)+    {+    }++    read_until_match_op_v2(read_until_match_op_v2&& other)+      : base_from_cancellation_state<ReadHandler>(+          ASIO_MOVE_CAST(base_from_cancellation_state<+            ReadHandler>)(other)),+        stream_(other.stream_),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),+        match_condition_(other.match_condition_),+        start_(other.start_),+        search_position_(other.search_position_),+        bytes_to_read_(other.bytes_to_read_),+        handler_(ASIO_MOVE_CAST(ReadHandler)(other.handler_))+    {+    }+#endif // defined(ASIO_HAS_MOVE)++    void operator()(asio::error_code ec,+        std::size_t bytes_transferred, int start = 0)+    {+      const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();+      std::size_t pos;+      switch (start_ = start)+      {+      case 1:+        for (;;)+        {+          {+            // Determine the range of the data to be searched.+            typedef typename DynamicBuffer_v2::const_buffers_type+              buffers_type;+            typedef buffers_iterator<buffers_type> iterator;+            buffers_type data_buffers =+              const_cast<const DynamicBuffer_v2&>(buffers_).data(+                  0, buffers_.size());+            iterator begin = iterator::begin(data_buffers);+            iterator start_pos = begin + search_position_;+            iterator end = iterator::end(data_buffers);++            // Look for a match.+            std::pair<iterator, bool> result = match_condition_(start_pos, end);+            if (result.second)+            {+              // Full match. We're done.+              search_position_ = result.first - begin;+              bytes_to_read_ = 0;+            }++            // No match yet. Check if buffer is full.+            else if (buffers_.size() == buffers_.max_size())+            {+              search_position_ = not_found;+              bytes_to_read_ = 0;+            }++            // Need to read some more data.+            else+            {+              if (result.first != end)+              {+                // Partial match. Next search needs to start from beginning of+                // match.+                search_position_ = result.first - begin;+              }+              else+              {+                // Next search can start with the new data.+                search_position_ = end - begin;+              }++              bytes_to_read_ = std::min<std::size_t>(+                    std::max<std::size_t>(512,+                      buffers_.capacity() - buffers_.size()),+                    std::min<std::size_t>(65536,+                      buffers_.max_size() - buffers_.size()));+            }+          }++          // Check if we're done.+          if (!start && bytes_to_read_ == 0)+            break;++          // Start a new asynchronous read operation to obtain more data.+          pos = buffers_.size();+          buffers_.grow(bytes_to_read_);+          {+            ASIO_HANDLER_LOCATION((+                  __FILE__, __LINE__, "async_read_until"));+            stream_.async_read_some(buffers_.data(pos, bytes_to_read_),+                ASIO_MOVE_CAST(read_until_match_op_v2)(*this));+          }+          return; default:+          buffers_.shrink(bytes_to_read_ - bytes_transferred);+          if (ec || bytes_transferred == 0)+            break;+          if (this->cancelled() != cancellation_type::none)+          {+            ec = error::operation_aborted;+            break;+          }+        }++        const asio::error_code result_ec =+          (search_position_ == not_found)+          ? error::not_found : ec;++        const std::size_t result_n =+          (ec || search_position_ == not_found)+          ? 0 : search_position_;++        ASIO_MOVE_OR_LVALUE(ReadHandler)(handler_)(result_ec, result_n);+      }+    }++  //private:+    AsyncReadStream& stream_;+    DynamicBuffer_v2 buffers_;+    MatchCondition match_condition_;+    int start_;+    std::size_t search_position_;+    std::size_t bytes_to_read_;+    ReadHandler handler_;+  };++  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename MatchCondition, typename ReadHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+        MatchCondition, ReadHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename MatchCondition, typename ReadHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+        MatchCondition, ReadHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream, typename DynamicBuffer_v2,+      typename MatchCondition, typename ReadHandler>+  inline bool asio_handler_is_continuation(+      read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+        MatchCondition, ReadHandler>* this_handler)+  {+    return this_handler->start_ == 0 ? true+      : asio_handler_cont_helpers::is_continuation(+          this_handler->handler_);+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename MatchCondition,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+        MatchCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncReadStream,+      typename DynamicBuffer_v2, typename MatchCondition,+      typename ReadHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,+      MatchCondition, ReadHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncReadStream>+  class initiate_async_read_until_match_v2+  {+  public:+    typedef typename AsyncReadStream::executor_type executor_type;++    explicit initiate_async_read_until_match_v2(AsyncReadStream& stream)+      : stream_(stream)+    {+    }++    executor_type get_executor() const ASIO_NOEXCEPT+    {+      return stream_.get_executor();+    }++    template <typename ReadHandler,+        typename DynamicBuffer_v2, typename MatchCondition>+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+        MatchCondition match_condition) const+    {+      // If you get an error on the following line it means that your handler+      // does not meet the documented type requirements for a ReadHandler.+      ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;++      non_const_lvalue<ReadHandler> handler2(handler);+      read_until_match_op_v2<AsyncReadStream,+        typename decay<DynamicBuffer_v2>::type,+          MatchCondition, typename decay<ReadHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+            match_condition, handler2.value)(asio::error_code(), 0, 1);+    }++  private:+    AsyncReadStream& stream_;+  };+} // namespace detail++#if !defined(GENERATING_DOCUMENTATION)++template <template <typename, typename> class Associator,+    typename AsyncReadStream, typename DynamicBuffer_v2,+    typename MatchCondition, typename ReadHandler, typename DefaultCandidate>+struct associator<Associator,+    detail::read_until_match_op_v2<AsyncReadStream,+      DynamicBuffer_v2, MatchCondition, ReadHandler>,+    DefaultCandidate>+  : Associator<ReadHandler, DefaultCandidate>+{+  static typename Associator<ReadHandler, DefaultCandidate>::type+  get(const detail::read_until_match_op_v2<AsyncReadStream,+        DynamicBuffer_v2, MatchCondition, ReadHandler>& h) ASIO_NOEXCEPT+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_);+  }++  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<ReadHandler, DefaultCandidate>::type)+  get(const detail::read_until_match_op_v2<AsyncReadStream,+        DynamicBuffer_v2, MatchCondition, ReadHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c)))+  {+    return Associator<ReadHandler, DefaultCandidate>::get(h.handler_, c);+  }+};++#endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncReadStream,+    typename DynamicBuffer_v2, typename MatchCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) ReadToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+    MatchCondition match_condition, ASIO_MOVE_ARG(ReadToken) token,+    typename constraint<+      is_match_condition<MatchCondition>::value+    >::type,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<ReadToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_read_until_match_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        match_condition)))+{+  return async_initiate<ReadToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_read_until_match_v2<AsyncReadStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+      match_condition);+}  #endif // !defined(ASIO_NO_EXTENSIONS) 
link/modules/asio-standalone/asio/include/asio/impl/redirect_error.hpp view
@@ -2,7 +2,7 @@ // impl/redirect_error.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,12 +16,13 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include "asio/associated_executor.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"-#include "asio/detail/initiation_base.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/system_error.hpp"  #include "asio/detail/push_options.hpp"@@ -39,47 +40,121 @@   template <typename CompletionToken>   redirect_error_handler(redirect_error_t<CompletionToken> e)     : ec_(e.ec_),-      handler_(static_cast<CompletionToken&&>(e.token_))+      handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_))   {   }    template <typename RedirectedHandler>   redirect_error_handler(asio::error_code& ec,-      RedirectedHandler&& h)+      ASIO_MOVE_ARG(RedirectedHandler) h)     : ec_(ec),-      handler_(static_cast<RedirectedHandler&&>(h))+      handler_(ASIO_MOVE_CAST(RedirectedHandler)(h))   {   }    void operator()()   {-    static_cast<Handler&&>(handler_)();+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)();   } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename Arg, typename... Args>-  enable_if_t<-    !is_same<decay_t<Arg>, asio::error_code>::value-  >-  operator()(Arg&& arg, Args&&... args)+  typename enable_if<+    !is_same<typename decay<Arg>::type, asio::error_code>::value+  >::type+  operator()(ASIO_MOVE_ARG(Arg) arg, ASIO_MOVE_ARG(Args)... args)   {-    static_cast<Handler&&>(handler_)(-        static_cast<Arg&&>(arg),-        static_cast<Args&&>(args)...);+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        ASIO_MOVE_CAST(Arg)(arg),+        ASIO_MOVE_CAST(Args)(args)...);   }    template <typename... Args>-  void operator()(const asio::error_code& ec, Args&&... args)+  void operator()(const asio::error_code& ec,+      ASIO_MOVE_ARG(Args)... args)   {     ec_ = ec;-    static_cast<Handler&&>(handler_)(static_cast<Args&&>(args)...);+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        ASIO_MOVE_CAST(Args)(args)...);   } +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename Arg>+  typename enable_if<+    !is_same<typename decay<Arg>::type, asio::error_code>::value+  >::type+  operator()(ASIO_MOVE_ARG(Arg) arg)+  {+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(+        ASIO_MOVE_CAST(Arg)(arg));+  }++  void operator()(const asio::error_code& ec)+  {+    ec_ = ec;+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)();+  }++#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \+  template <typename Arg, ASIO_VARIADIC_TPARAMS(n)> \+  typename enable_if< \+    !is_same<typename decay<Arg>::type, asio::error_code>::value \+  >::type \+  operator()(ASIO_MOVE_ARG(Arg) arg, ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)( \+        ASIO_MOVE_CAST(Arg)(arg), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  void operator()(const asio::error_code& ec, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    ec_ = ec; \+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)( \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF)+#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ //private:   asio::error_code& ec_;   Handler handler_; };  template <typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    redirect_error_handler<Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    redirect_error_handler<Handler>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Handler> inline bool asio_handler_is_continuation(     redirect_error_handler<Handler>* this_handler) {@@ -87,12 +162,38 @@         this_handler->handler_); } +template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    redirect_error_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    redirect_error_handler<Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Signature> struct redirect_error_signature {   typedef Signature type; }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename R, typename... Args> struct redirect_error_signature<R(asio::error_code, Args...)> {@@ -105,6 +206,8 @@   typedef R type(Args...); }; +# if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+ template <typename R, typename... Args> struct redirect_error_signature<R(asio::error_code, Args...) &> {@@ -129,7 +232,7 @@   typedef R type(Args...) &&; }; -#if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#  if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)  template <typename R, typename... Args> struct redirect_error_signature<@@ -173,8 +276,197 @@   typedef R type(Args...) && noexcept; }; -#endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+#  endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) +template <typename R>+struct redirect_error_signature<R(asio::error_code)>+{+  typedef R type();+};++template <typename R>+struct redirect_error_signature<R(const asio::error_code&)>+{+  typedef R type();+};++#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(asio::error_code, ASIO_VARIADIC_TARGS(n))> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)); \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(const asio::error_code&, ASIO_VARIADIC_TARGS(n))> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)); \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF)+#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF++# if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)++template <typename R>+struct redirect_error_signature<R(asio::error_code) &>+{+  typedef R type() &;+};++template <typename R>+struct redirect_error_signature<R(const asio::error_code&) &>+{+  typedef R type() &;+};++template <typename R>+struct redirect_error_signature<R(asio::error_code) &&>+{+  typedef R type() &&;+};++template <typename R>+struct redirect_error_signature<R(const asio::error_code&) &&>+{+  typedef R type() &&;+};++#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(asio::error_code, ASIO_VARIADIC_TARGS(n)) &> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) &; \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(const asio::error_code&, ASIO_VARIADIC_TARGS(n)) &> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) &; \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(asio::error_code, ASIO_VARIADIC_TARGS(n)) &&> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) &&; \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(const asio::error_code&, ASIO_VARIADIC_TARGS(n)) &&> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) &&; \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF)+#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF++#  if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)++template <typename R>+struct redirect_error_signature<+  R(asio::error_code) noexcept>+{+  typedef R type() noexcept;+};++template <typename R>+struct redirect_error_signature<+  R(const asio::error_code&) noexcept>+{+  typedef R type() noexcept;+};++template <typename R>+struct redirect_error_signature<+  R(asio::error_code) & noexcept>+{+  typedef R type() & noexcept;+};++template <typename R>+struct redirect_error_signature<+  R(const asio::error_code&) & noexcept>+{+  typedef R type() & noexcept;+};++template <typename R>+struct redirect_error_signature<+  R(asio::error_code) && noexcept>+{+  typedef R type() && noexcept;+};++template <typename R>+struct redirect_error_signature<+  R(const asio::error_code&) && noexcept>+{+  typedef R type() && noexcept;+};++#define ASIO_PRIVATE_REDIRECT_ERROR_DEF(n) \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(asio::error_code, ASIO_VARIADIC_TARGS(n)) noexcept> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) noexcept; \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(const asio::error_code&, \+        ASIO_VARIADIC_TARGS(n)) noexcept> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) noexcept; \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(asio::error_code, \+        ASIO_VARIADIC_TARGS(n)) & noexcept> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) & noexcept; \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(const asio::error_code&, \+        ASIO_VARIADIC_TARGS(n)) & noexcept> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) & noexcept; \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(asio::error_code, \+        ASIO_VARIADIC_TARGS(n)) && noexcept> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) && noexcept; \+  }; \+  \+  template <typename R, ASIO_VARIADIC_TPARAMS(n)> \+  struct redirect_error_signature< \+      R(const asio::error_code&, \+        ASIO_VARIADIC_TARGS(n)) && noexcept> \+  { \+    typedef R type(ASIO_VARIADIC_TARGS(n)) && noexcept; \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_REDIRECT_ERROR_DEF)+#undef ASIO_PRIVATE_REDIRECT_ERROR_DEF++#  endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE)+# endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS)+#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ } // namespace detail  #if !defined(GENERATING_DOCUMENTATION)@@ -184,53 +476,130 @@   : async_result<CompletionToken,       typename detail::redirect_error_signature<Signature>::type> {-  template <typename Initiation>-  struct init_wrapper : detail::initiation_base<Initiation>++  struct init_wrapper   {-    using detail::initiation_base<Initiation>::initiation_base;+    explicit init_wrapper(asio::error_code& ec)+      : ec_(ec)+    {+    } -    template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        asio::error_code* ec, Args&&... args) &&+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++    template <typename Handler, typename Initiation, typename... Args>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Initiation) initiation,+        ASIO_MOVE_ARG(Args)... args) const     {-      static_cast<Initiation&&>(*this)(-          detail::redirect_error_handler<decay_t<Handler>>(-            *ec, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation)(+          detail::redirect_error_handler<+            typename decay<Handler>::type>(+              ec_, ASIO_MOVE_CAST(Handler)(handler)),+          ASIO_MOVE_CAST(Args)(args)...);     } -    template <typename Handler, typename... Args>-    void operator()(Handler&& handler,-        asio::error_code* ec, Args&&... args) const &+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    template <typename Handler, typename Initiation>+    void operator()(+        ASIO_MOVE_ARG(Handler) handler,+        ASIO_MOVE_ARG(Initiation) initiation) const     {-      static_cast<const Initiation&>(*this)(-          detail::redirect_error_handler<decay_t<Handler>>(-            *ec, static_cast<Handler&&>(handler)),-          static_cast<Args&&>(args)...);+      ASIO_MOVE_CAST(Initiation)(initiation)(+          detail::redirect_error_handler<+            typename decay<Handler>::type>(+              ec_, ASIO_MOVE_CAST(Handler)(handler)));     }++#define ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \+    template <typename Handler, typename Initiation, \+        ASIO_VARIADIC_TPARAMS(n)> \+    void operator()( \+        ASIO_MOVE_ARG(Handler) handler, \+        ASIO_MOVE_ARG(Initiation) initiation, \+        ASIO_VARIADIC_MOVE_PARAMS(n)) const \+    { \+      ASIO_MOVE_CAST(Initiation)(initiation)( \+          detail::redirect_error_handler< \+            typename decay<Handler>::type>( \+              ec_, ASIO_MOVE_CAST(Handler)(handler)), \+          ASIO_VARIADIC_MOVE_ARGS(n)); \+    } \+    /**/+    ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INIT_WRAPPER_DEF)+#undef ASIO_PRIVATE_INIT_WRAPPER_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++    asio::error_code& ec_;   }; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<-        conditional_t<-          is_const<remove_reference_t<RawCompletionToken>>::value,-            const CompletionToken, CompletionToken>,+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken,+      typename detail::redirect_error_signature<Signature>::type,+      (async_initiate<CompletionToken,         typename detail::redirect_error_signature<Signature>::type>(-          declval<init_wrapper<decay_t<Initiation>>>(),-          token.token_, &token.ec_, static_cast<Args&&>(args)...))+          declval<init_wrapper>(), declval<CompletionToken&>(),+          declval<Initiation>(), declval<ASIO_MOVE_ARG(Args)>()...)))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token,+      ASIO_MOVE_ARG(Args)... args)   {-    return async_initiate<-      conditional_t<-        is_const<remove_reference_t<RawCompletionToken>>::value,-          const CompletionToken, CompletionToken>,+    return async_initiate<CompletionToken,       typename detail::redirect_error_signature<Signature>::type>(-        init_wrapper<decay_t<Initiation>>(-          static_cast<Initiation&&>(initiation)),-        token.token_, &token.ec_, static_cast<Args&&>(args)...);+        init_wrapper(token.ec_), token.token_,+        ASIO_MOVE_CAST(Initiation)(initiation),+        ASIO_MOVE_CAST(Args)(args)...);   }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename Initiation, typename RawCompletionToken>+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken,+      typename detail::redirect_error_signature<Signature>::type,+      (async_initiate<CompletionToken,+        typename detail::redirect_error_signature<Signature>::type>(+          declval<init_wrapper>(), declval<CompletionToken&>(),+          declval<Initiation>())))+  initiate(+      ASIO_MOVE_ARG(Initiation) initiation,+      ASIO_MOVE_ARG(RawCompletionToken) token)+  {+    return async_initiate<CompletionToken,+      typename detail::redirect_error_signature<Signature>::type>(+        init_wrapper(token.ec_), token.token_,+        ASIO_MOVE_CAST(Initiation)(initiation));+  }++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, typename RawCompletionToken, \+      ASIO_VARIADIC_TPARAMS(n)> \+  static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, \+      typename detail::redirect_error_signature<Signature>::type, \+      (async_initiate<CompletionToken, \+        typename detail::redirect_error_signature<Signature>::type>( \+          declval<init_wrapper>(), declval<CompletionToken&>(), \+          declval<Initiation>(), ASIO_VARIADIC_DECLVAL(n)))) \+  initiate( \+      ASIO_MOVE_ARG(Initiation) initiation, \+      ASIO_MOVE_ARG(RawCompletionToken) token, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    return async_initiate<CompletionToken, \+      typename detail::redirect_error_signature<Signature>::type>( \+        init_wrapper(token.ec_), token.token_, \+        ASIO_MOVE_CAST(Initiation)(initiation), \+        ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) };  template <template <typename, typename> class Associator,@@ -239,42 +608,20 @@     detail::redirect_error_handler<Handler>, DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const detail::redirect_error_handler<Handler>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const detail::redirect_error_handler<Handler>& h) ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const detail::redirect_error_handler<Handler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const detail::redirect_error_handler<Handler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);-  }-};--template <typename... Signatures>-struct async_result<partial_redirect_error, Signatures...>-{-  template <typename Initiation, typename RawCompletionToken, typename... Args>-  static auto initiate(Initiation&& initiation,-      RawCompletionToken&& token, Args&&... args)-    -> decltype(-      async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        redirect_error_t<-          default_completion_token_t<associated_executor_t<Initiation>>>(-            default_completion_token_t<associated_executor_t<Initiation>>{},-            token.ec_),-        static_cast<Args&&>(args)...))-  {-    return async_initiate<Signatures...>(-        static_cast<Initiation&&>(initiation),-        redirect_error_t<-          default_completion_token_t<associated_executor_t<Initiation>>>(-            default_completion_token_t<associated_executor_t<Initiation>>{},-            token.ec_),-        static_cast<Args&&>(args)...);   } }; 
link/modules/asio-standalone/asio/include/asio/impl/serial_port_base.hpp view
@@ -2,7 +2,7 @@ // impl/serial_port_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/impl/serial_port_base.ipp view
@@ -2,7 +2,7 @@ // impl/serial_port_base.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/impl/spawn.hpp view
@@ -2,7 +2,7 @@ // impl/spawn.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,7 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <tuple> #include "asio/associated_allocator.hpp" #include "asio/associated_cancellation_slot.hpp" #include "asio/associated_executor.hpp"@@ -24,15 +23,20 @@ #include "asio/bind_executor.hpp" #include "asio/detail/atomic_count.hpp" #include "asio/detail/bind_handler.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/memory.hpp" #include "asio/detail/noncopyable.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp"-#include "asio/disposition.hpp"-#include "asio/error.hpp"+#include "asio/detail/variadic_templates.hpp" #include "asio/system_error.hpp" +#if defined(ASIO_HAS_STD_TUPLE)+# include <tuple>+#endif // defined(ASIO_HAS_STD_TUPLE)+ #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) # include <boost/context/fiber.hpp> #endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)@@ -50,6 +54,137 @@ } #endif // !defined(ASIO_NO_EXCEPTIONS) +#if defined(ASIO_HAS_BOOST_COROUTINE)++// Spawned thread implementation using Boost.Coroutine.+class spawned_coroutine_thread : public spawned_thread_base+{+public:+#if defined(BOOST_COROUTINES_UNIDIRECT) || defined(BOOST_COROUTINES_V2)+  typedef boost::coroutines::pull_coroutine<void> callee_type;+  typedef boost::coroutines::push_coroutine<void> caller_type;+#else+  typedef boost::coroutines::coroutine<void()> callee_type;+  typedef boost::coroutines::coroutine<void()> caller_type;+#endif++  spawned_coroutine_thread(caller_type& caller)+    : caller_(caller),+      on_suspend_fn_(0),+      on_suspend_arg_(0)+  {+  }++  template <typename F>+  static spawned_thread_base* spawn(ASIO_MOVE_ARG(F) f,+      const boost::coroutines::attributes& attributes,+      cancellation_slot parent_cancel_slot = cancellation_slot(),+      cancellation_state cancel_state = cancellation_state())+  {+    spawned_coroutine_thread* spawned_thread = 0;+    callee_type callee(entry_point<typename decay<F>::type>(+          ASIO_MOVE_CAST(F)(f), &spawned_thread), attributes);+    spawned_thread->callee_.swap(callee);+    spawned_thread->parent_cancellation_slot_ = parent_cancel_slot;+    spawned_thread->cancellation_state_ = cancel_state;+    return spawned_thread;+  }++  template <typename F>+  static spawned_thread_base* spawn(ASIO_MOVE_ARG(F) f,+      cancellation_slot parent_cancel_slot = cancellation_slot(),+      cancellation_state cancel_state = cancellation_state())+  {+    return spawn(ASIO_MOVE_CAST(F)(f), boost::coroutines::attributes(),+        parent_cancel_slot, cancel_state);+  }++  void resume()+  {+    callee_();+    if (on_suspend_fn_)+    {+      void (*fn)(void*) = on_suspend_fn_;+      void* arg = on_suspend_arg_;+      on_suspend_fn_ = 0;+      fn(arg);+    }+  }++  void suspend_with(void (*fn)(void*), void* arg)+  {+    if (throw_if_cancelled_)+      if (!!cancellation_state_.cancelled())+        throw_error(asio::error::operation_aborted, "yield");+    has_context_switched_ = true;+    on_suspend_fn_ = fn;+    on_suspend_arg_ = arg;+    caller_();+  }++  void destroy()+  {+    callee_type callee;+    callee.swap(callee_);+    if (terminal_)+      callee();+  }++private:+  template <typename Function>+  class entry_point+  {+  public:+    template <typename F>+    entry_point(ASIO_MOVE_ARG(F) f,+        spawned_coroutine_thread** spawned_thread_out)+      : function_(ASIO_MOVE_CAST(F)(f)),+        spawned_thread_out_(spawned_thread_out)+    {+    }++    void operator()(caller_type& caller)+    {+      Function function(ASIO_MOVE_CAST(Function)(function_));+      spawned_coroutine_thread spawned_thread(caller);+      *spawned_thread_out_ = &spawned_thread;+      spawned_thread_out_ = 0;+      spawned_thread.suspend();+#if !defined(ASIO_NO_EXCEPTIONS)+      try+#endif // !defined(ASIO_NO_EXCEPTIONS)+      {+        function(&spawned_thread);+        spawned_thread.terminal_ = true;+        spawned_thread.suspend();+      }+#if !defined(ASIO_NO_EXCEPTIONS)+      catch (const boost::coroutines::detail::forced_unwind&)+      {+        throw;+      }+      catch (...)+      {+        exception_ptr ex = current_exception();+        spawned_thread.terminal_ = true;+        spawned_thread.suspend_with(spawned_thread_rethrow, &ex);+      }+#endif // !defined(ASIO_NO_EXCEPTIONS)+    }++  private:+    Function function_;+    spawned_coroutine_thread** spawned_thread_out_;+  };++  caller_type& caller_;+  callee_type callee_;+  void (*on_suspend_fn_)(void*);+  void* on_suspend_arg_;+};++#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER)  // Spawned thread implementation using Boost.Context's fiber.@@ -58,8 +193,8 @@ public:   typedef boost::context::fiber fiber_type; -  spawned_fiber_thread(fiber_type&& caller)-    : caller_(static_cast<fiber_type&&>(caller)),+  spawned_fiber_thread(ASIO_MOVE_ARG(fiber_type) caller)+    : caller_(ASIO_MOVE_CAST(fiber_type)(caller)),       on_suspend_fn_(0),       on_suspend_arg_(0)   {@@ -67,35 +202,35 @@    template <typename StackAllocator, typename F>   static spawned_thread_base* spawn(allocator_arg_t,-      StackAllocator&& stack_allocator,-      F&& f,+      ASIO_MOVE_ARG(StackAllocator) stack_allocator,+      ASIO_MOVE_ARG(F) f,       cancellation_slot parent_cancel_slot = cancellation_slot(),       cancellation_state cancel_state = cancellation_state())   {     spawned_fiber_thread* spawned_thread = 0;     fiber_type callee(allocator_arg_t(),-        static_cast<StackAllocator&&>(stack_allocator),-        entry_point<decay_t<F>>(-          static_cast<F&&>(f), &spawned_thread));-    callee = fiber_type(static_cast<fiber_type&&>(callee)).resume();-    spawned_thread->callee_ = static_cast<fiber_type&&>(callee);+        ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+        entry_point<typename decay<F>::type>(+          ASIO_MOVE_CAST(F)(f), &spawned_thread));+    callee = fiber_type(ASIO_MOVE_CAST(fiber_type)(callee)).resume();+    spawned_thread->callee_ = ASIO_MOVE_CAST(fiber_type)(callee);     spawned_thread->parent_cancellation_slot_ = parent_cancel_slot;     spawned_thread->cancellation_state_ = cancel_state;     return spawned_thread;   }    template <typename F>-  static spawned_thread_base* spawn(F&& f,+  static spawned_thread_base* spawn(ASIO_MOVE_ARG(F) f,       cancellation_slot parent_cancel_slot = cancellation_slot(),       cancellation_state cancel_state = cancellation_state())   {     return spawn(allocator_arg_t(), boost::context::fixedsize_stack(),-        static_cast<F&&>(f), parent_cancel_slot, cancel_state);+        ASIO_MOVE_CAST(F)(f), parent_cancel_slot, cancel_state);   }    void resume()   {-    callee_ = fiber_type(static_cast<fiber_type&&>(callee_)).resume();+    callee_ = fiber_type(ASIO_MOVE_CAST(fiber_type)(callee_)).resume();     if (on_suspend_fn_)     {       void (*fn)(void*) = on_suspend_fn_;@@ -113,14 +248,14 @@     has_context_switched_ = true;     on_suspend_fn_ = fn;     on_suspend_arg_ = arg;-    caller_ = fiber_type(static_cast<fiber_type&&>(caller_)).resume();+    caller_ = fiber_type(ASIO_MOVE_CAST(fiber_type)(caller_)).resume();   }    void destroy()   {-    fiber_type callee = static_cast<fiber_type&&>(callee_);+    fiber_type callee = ASIO_MOVE_CAST(fiber_type)(callee_);     if (terminal_)-      fiber_type(static_cast<fiber_type&&>(callee)).resume();+      fiber_type(ASIO_MOVE_CAST(fiber_type)(callee)).resume();   }  private:@@ -129,18 +264,18 @@   {   public:     template <typename F>-    entry_point(F&& f,+    entry_point(ASIO_MOVE_ARG(F) f,         spawned_fiber_thread** spawned_thread_out)-      : function_(static_cast<F&&>(f)),+      : function_(ASIO_MOVE_CAST(F)(f)),         spawned_thread_out_(spawned_thread_out)     {     } -    fiber_type operator()(fiber_type&& caller)+    fiber_type operator()(ASIO_MOVE_ARG(fiber_type) caller)     {-      Function function(static_cast<Function&&>(function_));+      Function function(ASIO_MOVE_CAST(Function)(function_));       spawned_fiber_thread spawned_thread(-          static_cast<fiber_type&&>(caller));+          ASIO_MOVE_CAST(fiber_type)(caller));       *spawned_thread_out_ = &spawned_thread;       spawned_thread_out_ = 0;       spawned_thread.suspend();@@ -164,7 +299,7 @@         spawned_thread.suspend_with(spawned_thread_rethrow, &ex);       } #endif // !defined(ASIO_NO_EXCEPTIONS)-      return static_cast<fiber_type&&>(spawned_thread.caller_);+      return ASIO_MOVE_CAST(fiber_type)(spawned_thread.caller_);     }    private:@@ -182,6 +317,8 @@  #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) typedef spawned_fiber_thread default_spawned_thread_type;+#elif defined(ASIO_HAS_BOOST_COROUTINE)+typedef spawned_coroutine_thread default_spawned_thread_type; #else # error No spawn() implementation available #endif@@ -193,14 +330,32 @@   explicit spawned_thread_resumer(spawned_thread_base* spawned_thread)     : spawned_thread_(spawned_thread)   {+#if !defined(ASIO_HAS_MOVE)+    spawned_thread->detach();+    spawned_thread->attach(&spawned_thread_);+#endif // !defined(ASIO_HAS_MOVE)   } -  spawned_thread_resumer(spawned_thread_resumer&& other) noexcept+#if defined(ASIO_HAS_MOVE)++  spawned_thread_resumer(spawned_thread_resumer&& other) ASIO_NOEXCEPT     : spawned_thread_(other.spawned_thread_)   {     other.spawned_thread_ = 0;   } +#else // defined(ASIO_HAS_MOVE)++  spawned_thread_resumer(+      const spawned_thread_resumer& other) ASIO_NOEXCEPT+    : spawned_thread_(other.spawned_thread_)+  {+    spawned_thread_->detach();+    spawned_thread_->attach(&spawned_thread_);+  }++#endif // defined(ASIO_HAS_MOVE)+   ~spawned_thread_resumer()   {     if (spawned_thread_)@@ -209,7 +364,9 @@    void operator()()   {+#if defined(ASIO_HAS_MOVE)     spawned_thread_->attach(&spawned_thread_);+#endif // defined(ASIO_HAS_MOVE)     spawned_thread_->resume();   } @@ -225,14 +382,31 @@     : spawned_thread_(spawned_thread)   {     spawned_thread->detach();+#if !defined(ASIO_HAS_MOVE)+    spawned_thread->attach(&spawned_thread_);+#endif // !defined(ASIO_HAS_MOVE)   } -  spawned_thread_destroyer(spawned_thread_destroyer&& other) noexcept+#if defined(ASIO_HAS_MOVE)++  spawned_thread_destroyer(spawned_thread_destroyer&& other) ASIO_NOEXCEPT     : spawned_thread_(other.spawned_thread_)   {     other.spawned_thread_ = 0;   } +#else // defined(ASIO_HAS_MOVE)++  spawned_thread_destroyer(+      const spawned_thread_destroyer& other) ASIO_NOEXCEPT+    : spawned_thread_(other.spawned_thread_)+  {+    spawned_thread_->detach();+    spawned_thread_->attach(&spawned_thread_);+  }++#endif // defined(ASIO_HAS_MOVE)+   ~spawned_thread_destroyer()   {     if (spawned_thread_)@@ -265,9 +439,14 @@       spawned_thread_(yield.spawned_thread_)   {     spawned_thread_->detach();+#if !defined(ASIO_HAS_MOVE)+    spawned_thread_->attach(&spawned_thread_);+#endif // !defined(ASIO_HAS_MOVE)   } -  spawn_handler_base(spawn_handler_base&& other) noexcept+#if defined(ASIO_HAS_MOVE)++  spawn_handler_base(spawn_handler_base&& other) ASIO_NOEXCEPT     : yield_(other.yield_),       spawned_thread_(other.spawned_thread_) @@ -275,18 +454,30 @@     other.spawned_thread_ = 0;   } +#else // defined(ASIO_HAS_MOVE)++  spawn_handler_base(const spawn_handler_base& other) ASIO_NOEXCEPT+    : yield_(other.yield_),+      spawned_thread_(other.spawned_thread_)+  {+    spawned_thread_->detach();+    spawned_thread_->attach(&spawned_thread_);+  }++#endif // defined(ASIO_HAS_MOVE)+   ~spawn_handler_base()   {     if (spawned_thread_)       (post)(yield_.executor_, spawned_thread_destroyer(spawned_thread_));   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return yield_.executor_;   } -  cancellation_slot_type get_cancellation_slot() const noexcept+  cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT   {     return spawned_thread_->get_cancellation_slot();   }@@ -304,7 +495,7 @@ };  // Completion handlers for when basic_yield_context is used as a token.-template <typename Executor, typename Signature, typename = void>+template <typename Executor, typename Signature> class spawn_handler;  template <typename Executor, typename R>@@ -367,14 +558,13 @@   result_type& result_; }; -template <typename Executor, typename R, typename Disposition>-class spawn_handler<Executor, R(Disposition),-    enable_if_t<is_disposition<Disposition>::value>-  > : public spawn_handler_base<Executor>+template <typename Executor, typename R>+class spawn_handler<Executor, R(exception_ptr)>+  : public spawn_handler_base<Executor> { public:   typedef void return_type;-  typedef Disposition* result_type;+  typedef exception_ptr* result_type;    spawn_handler(const basic_yield_context<Executor>& yield, result_type& result)     : spawn_handler_base<Executor>(yield),@@ -382,16 +572,16 @@   {   } -  void operator()(Disposition d)+  void operator()(exception_ptr ex)   {-    result_ = detail::addressof(d);+    result_ = &ex;     this->resume();   }    static return_type on_resume(result_type& result)   {-    if (*result != no_error)-      asio::throw_exception(static_cast<Disposition&&>(*result));+    if (result)+      rethrow_exception(*result);   }  private:@@ -399,9 +589,8 @@ };  template <typename Executor, typename R, typename T>-class spawn_handler<Executor, R(T),-    enable_if_t<!is_disposition<T>::value>-  > : public spawn_handler_base<Executor>+class spawn_handler<Executor, R(T)>+  : public spawn_handler_base<Executor> { public:   typedef T return_type;@@ -415,13 +604,13 @@    void operator()(T value)   {-    result_ = detail::addressof(value);+    result_ = &value;     this->resume();   }    static return_type on_resume(result_type& result)   {-    return static_cast<return_type&&>(*result);+    return ASIO_MOVE_CAST(return_type)(*result);   }  private:@@ -456,7 +645,7 @@     }     else       result_.ec_ = &ec;-    result_.value_ = detail::addressof(value);+    result_.value_ = &value;     this->resume();   } @@ -464,24 +653,23 @@   {     if (result.ec_)       throw_error(*result.ec_);-    return static_cast<return_type&&>(*result.value_);+    return ASIO_MOVE_CAST(return_type)(*result.value_);   }  private:   result_type& result_; }; -template <typename Executor, typename R, typename Disposition, typename T>-class spawn_handler<Executor, R(Disposition, T),-    enable_if_t<is_disposition<Disposition>::value>-  > : public spawn_handler_base<Executor>+template <typename Executor, typename R, typename T>+class spawn_handler<Executor, R(exception_ptr, T)>+  : public spawn_handler_base<Executor> { public:   typedef T return_type;    struct result_type   {-    Disposition* disposition_;+    exception_ptr ex_;     return_type* value_;   }; @@ -491,34 +679,33 @@   {   } -  void operator()(Disposition d, T value)+  void operator()(exception_ptr ex, T value)   {-    result_.disposition_ = detail::addressof(d);-    result_.value_ = detail::addressof(value);+    result_.ex_ = &ex;+    result_.value_ = &value;     this->resume();   }    static return_type on_resume(result_type& result)   {-    if (*result.disposition_ != no_error)-    {-      asio::throw_exception(-          static_cast<Disposition&&>(*result.disposition_));-    }-    return static_cast<return_type&&>(*result.value_);+    if (result.ex_)+      rethrow_exception(*result.ex_);+    return ASIO_MOVE_CAST(return_type)(*result.value_);   }  private:   result_type& result_; }; -template <typename Executor, typename R, typename T, typename... Ts>-class spawn_handler<Executor, R(T, Ts...),-    enable_if_t<!is_disposition<T>::value>-  > : public spawn_handler_base<Executor>+#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  && defined(ASIO_HAS_STD_TUPLE)++template <typename Executor, typename R, typename... Ts>+class spawn_handler<Executor, R(Ts...)>+  : public spawn_handler_base<Executor> { public:-  typedef std::tuple<T, Ts...> return_type;+  typedef std::tuple<Ts...> return_type;    typedef return_type* result_type; @@ -529,16 +716,16 @@   }    template <typename... Args>-  void operator()(Args&&... args)+  void operator()(ASIO_MOVE_ARG(Args)... args)   {-    return_type value(static_cast<Args&&>(args)...);-    result_ = detail::addressof(value);+    return_type value(ASIO_MOVE_CAST(Args)(args)...);+    result_ = &value;     this->resume();   }    static return_type on_resume(result_type& result)   {-    return static_cast<return_type&&>(*result);+    return ASIO_MOVE_CAST(return_type)(*result);   }  private:@@ -566,9 +753,9 @@    template <typename... Args>   void operator()(asio::error_code ec,-      Args&&... args)+      ASIO_MOVE_ARG(Args)... args)   {-    return_type value(static_cast<Args&&>(args)...);+    return_type value(ASIO_MOVE_CAST(Args)(args)...);     if (this->yield_.ec_)     {       *this->yield_.ec_ = ec;@@ -576,7 +763,7 @@     }     else       result_.ec_ = &ec;-    result_.value_ = detail::addressof(value);+    result_.value_ = &value;     this->resume();   } @@ -584,24 +771,23 @@   {     if (result.ec_)       throw_error(*result.ec_);-    return static_cast<return_type&&>(*result.value_);+    return ASIO_MOVE_CAST(return_type)(*result.value_);   }  private:   result_type& result_; }; -template <typename Executor, typename R, typename Disposition, typename... Ts>-class spawn_handler<Executor, R(Disposition, Ts...),-    enable_if_t<is_disposition<Disposition>::value>-  > : public spawn_handler_base<Executor>+template <typename Executor, typename R, typename... Ts>+class spawn_handler<Executor, R(exception_ptr, Ts...)>+  : public spawn_handler_base<Executor> { public:   typedef std::tuple<Ts...> return_type;    struct result_type   {-    Disposition* disposition_;+    exception_ptr ex_;     return_type* value_;   }; @@ -612,28 +798,28 @@   }    template <typename... Args>-  void operator()(Disposition d, Args&&... args)+  void operator()(exception_ptr ex, ASIO_MOVE_ARG(Args)... args)   {-    return_type value(static_cast<Args&&>(args)...);-    result_.disposition_ = detail::addressof(d);-    result_.value_ = detail::addressof(value);+    return_type value(ASIO_MOVE_CAST(Args)(args)...);+    result_.ex_ = &ex;+    result_.value_ = &value;     this->resume();   }    static return_type on_resume(result_type& result)   {-    if (*result.disposition_ != no_error)-    {-      asio::throw_exception(-          static_cast<Disposition&&>(*result.disposition_));-    }-    return static_cast<return_type&&>(*result.value_);+    if (result.ex_)+      rethrow_exception(*result.ex_);+    return ASIO_MOVE_CAST(return_type)(*result.value_);   }  private:   result_type& result_; }; +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   && defined(ASIO_HAS_STD_TUPLE)+ template <typename Executor, typename Signature> inline bool asio_handler_is_continuation(spawn_handler<Executor, Signature>*) {@@ -642,8 +828,6 @@  } // namespace detail -#if !defined(GENERATING_DOCUMENTATION)- template <typename Executor, typename Signature> class async_result<basic_yield_context<Executor>, Signature> {@@ -651,12 +835,13 @@   typedef typename detail::spawn_handler<Executor, Signature> handler_type;   typedef typename handler_type::return_type return_type; -#if defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+# if defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)    template <typename Initiation, typename... InitArgs>-  static return_type initiate(Initiation&& init,+  static return_type initiate(ASIO_MOVE_ARG(Initiation) init,       const basic_yield_context<Executor>& yield,-      InitArgs&&... init_args)+      ASIO_MOVE_ARG(InitArgs)... init_args)   {     typename handler_type::result_type result       = typename handler_type::result_type();@@ -664,30 +849,30 @@     yield.spawned_thread_->suspend_with(         [&]()         {-          static_cast<Initiation&&>(init)(+          ASIO_MOVE_CAST(Initiation)(init)(               handler_type(yield, result),-              static_cast<InitArgs&&>(init_args)...);+              ASIO_MOVE_CAST(InitArgs)(init_args)...);         });      return handler_type::on_resume(result);   } -#else // defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)+# else // defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)    template <typename Initiation, typename... InitArgs>   struct suspend_with_helper   {     typename handler_type::result_type& result_;-    Initiation&& init_;+    ASIO_MOVE_ARG(Initiation) init_;     const basic_yield_context<Executor>& yield_;-    std::tuple<InitArgs&&...> init_args_;+    std::tuple<ASIO_MOVE_ARG(InitArgs)...> init_args_;      template <std::size_t... I>     void do_invoke(detail::index_sequence<I...>)     {-      static_cast<Initiation&&>(init_)(+      ASIO_MOVE_CAST(Initiation)(init_)(           handler_type(yield_, result_),-          static_cast<InitArgs&&>(std::get<I>(init_args_))...);+          ASIO_MOVE_CAST(InitArgs)(std::get<I>(init_args_))...);     }      void operator()()@@ -697,27 +882,123 @@   };    template <typename Initiation, typename... InitArgs>-  static return_type initiate(Initiation&& init,+  static return_type initiate(ASIO_MOVE_ARG(Initiation) init,       const basic_yield_context<Executor>& yield,-      InitArgs&&... init_args)+      ASIO_MOVE_ARG(InitArgs)... init_args)   {     typename handler_type::result_type result       = typename handler_type::result_type();      yield.spawned_thread_->suspend_with(       suspend_with_helper<Initiation, InitArgs...>{-          result, static_cast<Initiation&&>(init), yield,-          std::tuple<InitArgs&&...>(-            static_cast<InitArgs&&>(init_args)...)});+          result, ASIO_MOVE_CAST(Initiation)(init), yield,+          std::tuple<ASIO_MOVE_ARG(InitArgs)...>(+            ASIO_MOVE_CAST(InitArgs)(init_args)...)});      return handler_type::on_resume(result);   } -#endif // defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)-};+# endif // defined(ASIO_HAS_VARIADIC_LAMBDA_CAPTURES)+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) -#endif // !defined(GENERATING_DOCUMENTATION)+  template <typename Initiation>+  static return_type initiate(Initiation init,+      const basic_yield_context<Executor>& yield)+  {+    typename handler_type::result_type result+      = typename handler_type::result_type(); +    struct on_suspend+    {+      Initiation& init_;+      const basic_yield_context<Executor>& yield_;+      typename handler_type::result_type& result_;++      void do_call()+      {+        ASIO_MOVE_CAST(Initiation)(init_)(+            handler_type(yield_, result_));+      }++      static void call(void* arg)+      {+        static_cast<on_suspend*>(arg)->do_call();+      }+    } o = { init, yield, result };++    yield.spawned_thread_->suspend_with(&on_suspend::call, &o);++    return handler_type::on_resume(result);+  }++#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS(n) \+  ASIO_PRIVATE_ON_SUSPEND_MEMBERS_##n+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_1 \+  T1& x1;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_2 \+  T1& x1; T2& x2;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_3 \+  T1& x1; T2& x2; T3& x3;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_4 \+  T1& x1; T2& x2; T3& x3; T4& x4;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_5 \+  T1& x1; T2& x2; T3& x3; T4& x4; T5& x5;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_6 \+  T1& x1; T2& x2; T3& x3; T4& x4; T5& x5; T6& x6;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_7 \+  T1& x1; T2& x2; T3& x3; T4& x4; T5& x5; T6& x6; T7& x7;+#define ASIO_PRIVATE_ON_SUSPEND_MEMBERS_8 \+  T1& x1; T2& x2; T3& x3; T4& x4; T5& x5; T6& x6; T7& x7; T8& x8;++#define ASIO_PRIVATE_INITIATE_DEF(n) \+  template <typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \+  static return_type initiate(Initiation init, \+      const basic_yield_context<Executor>& yield, \+      ASIO_VARIADIC_BYVAL_PARAMS(n)) \+  { \+    typename handler_type::result_type result \+      = typename handler_type::result_type(); \+  \+    struct on_suspend \+    { \+      Initiation& init; \+      const basic_yield_context<Executor>& yield; \+      typename handler_type::result_type& result; \+      ASIO_PRIVATE_ON_SUSPEND_MEMBERS(n) \+  \+      void do_call() \+      { \+        ASIO_MOVE_CAST(Initiation)(init)( \+            handler_type(yield, result), \+            ASIO_VARIADIC_MOVE_ARGS(n)); \+      } \+  \+      static void call(void* arg) \+      { \+        static_cast<on_suspend*>(arg)->do_call(); \+      } \+    } o = { init, yield, result, ASIO_VARIADIC_BYVAL_ARGS(n) }; \+  \+    yield.spawned_thread_->suspend_with(&on_suspend::call, &o); \+  \+    return handler_type::on_resume(result); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)+#undef ASIO_PRIVATE_INITIATE_DEF+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_1+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_2+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_3+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_4+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_5+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_6+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_7+#undef ASIO_PRIVATE_ON_SUSPEND_MEMBERS_8++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+};+ namespace detail {  template <typename Executor, typename Function, typename Handler>@@ -726,10 +1007,10 @@ public:   template <typename F, typename H>   spawn_entry_point(const Executor& ex,-      F&& f, H&& h)+      ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(H) h)     : executor_(ex),-      function_(static_cast<F&&>(f)),-      handler_(static_cast<H&&>(h)),+      function_(ASIO_MOVE_CAST(F)(f)),+      handler_(ASIO_MOVE_CAST(H)(h)),       work_(handler_, executor_)   {   }@@ -738,7 +1019,8 @@   {     const basic_yield_context<Executor> yield(spawned_thread, executor_);     this->call(yield,-        void_type<result_of_t<Function(basic_yield_context<Executor>)>>());+        void_type<typename result_of<Function(+          basic_yield_context<Executor>)>::type>());   }  private:@@ -762,6 +1044,12 @@       throw;     } # endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)+# if defined(ASIO_HAS_BOOST_COROUTINE)+    catch (const boost::coroutines::detail::forced_unwind&)+    {+      throw;+    }+# endif // defined(ASIO_HAS_BOOST_COROUTINE)     catch (...)     {       exception_ptr ex = current_exception();@@ -783,9 +1071,8 @@       T result(function_(yield));       if (!yield.spawned_thread_->has_context_switched())         (post)(yield);-      detail::move_binder2<Handler, exception_ptr, T>-        handler(0, static_cast<Handler&&>(handler_),-          exception_ptr(), static_cast<T&&>(result));+      detail::binder2<Handler, exception_ptr, T>+        handler(handler_, exception_ptr(), ASIO_MOVE_CAST(T)(result));       work_.complete(handler, handler.handler_);     } #if !defined(ASIO_NO_EXCEPTIONS)@@ -795,13 +1082,18 @@       throw;     } # endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)+# if defined(ASIO_HAS_BOOST_COROUTINE)+    catch (const boost::coroutines::detail::forced_unwind&)+    {+      throw;+    }+# endif // defined(ASIO_HAS_BOOST_COROUTINE)     catch (...)     {       exception_ptr ex = current_exception();       if (!yield.spawned_thread_->has_context_switched())         (post)(yield);-      detail::move_binder2<Handler, exception_ptr, T>-        handler(0, static_cast<Handler&&>(handler_), ex, T());+      detail::binder2<Handler, exception_ptr, T> handler(handler_, ex, T());       work_.complete(handler, handler.handler_);     } #endif // !defined(ASIO_NO_EXCEPTIONS)@@ -849,15 +1141,16 @@   Executor ex_; }; + template <typename Handler, typename Executor> class spawn_cancellation_handler<Handler, Executor,-    enable_if_t<+    typename enable_if<       is_same<         typename associated_executor<Handler,           Executor>::asio_associated_executor_is_unspecialised,         void       >::value-    >>+    >::type> { public:   spawn_cancellation_handler(const Handler&, const Executor&)@@ -889,21 +1182,21 @@   {   } -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return executor_;   }    template <typename Handler, typename F>-  void operator()(Handler&& handler,-      F&& f) const+  void operator()(ASIO_MOVE_ARG(Handler) handler,+      ASIO_MOVE_ARG(F) f) const   {-    typedef decay_t<Handler> handler_type;-    typedef decay_t<F> function_type;+    typedef typename decay<Handler>::type handler_type;+    typedef typename decay<F>::type function_type;     typedef spawn_cancellation_handler<       handler_type, Executor> cancel_handler_type; -    associated_cancellation_slot_t<handler_type> slot+    typename associated_cancellation_slot<handler_type>::type slot       = asio::get_associated_cancellation_slot(handler);      cancel_handler_type* cancel_handler = slot.is_connected()@@ -921,24 +1214,24 @@         spawned_thread_resumer(           default_spawned_thread_type::spawn(             spawn_entry_point<Executor, function_type, handler_type>(-              executor_, static_cast<F&&>(f),-              static_cast<Handler&&>(handler)),+              executor_, ASIO_MOVE_CAST(F)(f),+              ASIO_MOVE_CAST(Handler)(handler)),             proxy_slot, cancel_state)));   }  #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER)    template <typename Handler, typename StackAllocator, typename F>-  void operator()(Handler&& handler, allocator_arg_t,-      StackAllocator&& stack_allocator,-      F&& f) const+  void operator()(ASIO_MOVE_ARG(Handler) handler, allocator_arg_t,+      ASIO_MOVE_ARG(StackAllocator) stack_allocator,+      ASIO_MOVE_ARG(F) f) const   {-    typedef decay_t<Handler> handler_type;-    typedef decay_t<F> function_type;+    typedef typename decay<Handler>::type handler_type;+    typedef typename decay<F>::type function_type;     typedef spawn_cancellation_handler<       handler_type, Executor> cancel_handler_type; -    associated_cancellation_slot_t<handler_type> slot+    typename associated_cancellation_slot<handler_type>::type slot       = asio::get_associated_cancellation_slot(handler);      cancel_handler_type* cancel_handler = slot.is_connected()@@ -955,10 +1248,10 @@     (dispatch)(executor_,         spawned_thread_resumer(           spawned_fiber_thread::spawn(allocator_arg_t(),-            static_cast<StackAllocator&&>(stack_allocator),+            ASIO_MOVE_CAST(StackAllocator)(stack_allocator),             spawn_entry_point<Executor, function_type, handler_type>(-              executor_, static_cast<F&&>(f),-              static_cast<Handler&&>(handler)),+              executor_, ASIO_MOVE_CAST(F)(f),+              ASIO_MOVE_CAST(Handler)(handler)),             proxy_slot, cancel_state)));   } @@ -972,141 +1265,349 @@  template <typename Executor, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type) CompletionToken>-inline auto spawn(const Executor& ex, F&& function, CompletionToken&& token,-    constraint_t<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+        CompletionToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const Executor& ex, ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token,+#if defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<+      !is_same<+        typename decay<CompletionToken>::type,+        boost::coroutines::attributes+      >::value+    >::type,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    >)-  -> decltype(+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<Executor>)>>::type>(-          declval<detail::initiate_spawn<Executor>>(),-          token, static_cast<F&&>(function)))+        typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+          declval<detail::initiate_spawn<Executor> >(),+          token, ASIO_MOVE_CAST(F)(function)))) {   return async_initiate<CompletionToken,     typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type>(+      typename result_of<F(basic_yield_context<Executor>)>::type>::type>(         detail::initiate_spawn<Executor>(ex),-        token, static_cast<F&&>(function));+        token, ASIO_MOVE_CAST(F)(function)); }  template <typename ExecutionContext, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<-        typename ExecutionContext::executor_type>)>>::type) CompletionToken>-inline auto spawn(ExecutionContext& ctx, F&& function, CompletionToken&& token,-    constraint_t<+      typename result_of<F(basic_yield_context<+        typename ExecutionContext::executor_type>)>::type>::type)+          CompletionToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<+        typename ExecutionContext::executor_type>)>::type>::type)+spawn(ExecutionContext& ctx, ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token,+#if defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<+      !is_same<+        typename decay<CompletionToken>::type,+        boost::coroutines::attributes+      >::value+    >::type,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    >)-  -> decltype(+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<-          typename ExecutionContext::executor_type>)>>::type>(+        typename result_of<F(basic_yield_context<+          typename ExecutionContext::executor_type>)>::type>::type>(             declval<detail::initiate_spawn<-              typename ExecutionContext::executor_type>>(),-            token, static_cast<F&&>(function)))+              typename ExecutionContext::executor_type> >(),+            token, ASIO_MOVE_CAST(F)(function)))) {-  return (spawn)(ctx.get_executor(), static_cast<F&&>(function),-      static_cast<CompletionToken&&>(token));+  return (spawn)(ctx.get_executor(), ASIO_MOVE_CAST(F)(function),+      ASIO_MOVE_CAST(CompletionToken)(token)); }  template <typename Executor, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type)+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)         CompletionToken>-inline auto spawn(const basic_yield_context<Executor>& ctx,-    F&& function, CompletionToken&& token,-    constraint_t<+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const basic_yield_context<Executor>& ctx,+    ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token,+#if defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<+      !is_same<+        typename decay<CompletionToken>::type,+        boost::coroutines::attributes+      >::value+    >::type,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    >)-  -> decltype(+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<Executor>)>>::type>(-          declval<detail::initiate_spawn<Executor>>(),-          token, static_cast<F&&>(function)))+        typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+          declval<detail::initiate_spawn<Executor> >(),+          token, ASIO_MOVE_CAST(F)(function)))) {-  return (spawn)(ctx.get_executor(), static_cast<F&&>(function),-      static_cast<CompletionToken&&>(token));+  return (spawn)(ctx.get_executor(), ASIO_MOVE_CAST(F)(function),+      ASIO_MOVE_CAST(CompletionToken)(token)); }  #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER)  template <typename Executor, typename StackAllocator, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type)+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)         CompletionToken>-inline auto spawn(const Executor& ex, allocator_arg_t,-    StackAllocator&& stack_allocator, F&& function, CompletionToken&& token,-    constraint_t<+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const Executor& ex, allocator_arg_t,+    ASIO_MOVE_ARG(StackAllocator) stack_allocator,+    ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token,+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    >)-  -> decltype(+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<Executor>)>>::type>(-          declval<detail::initiate_spawn<Executor>>(),+        typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+          declval<detail::initiate_spawn<Executor> >(),           token, allocator_arg_t(),-          static_cast<StackAllocator&&>(stack_allocator),-          static_cast<F&&>(function)))+          ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+          ASIO_MOVE_CAST(F)(function)))) {   return async_initiate<CompletionToken,     typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type>(+      typename result_of<F(basic_yield_context<Executor>)>::type>::type>(         detail::initiate_spawn<Executor>(ex), token, allocator_arg_t(),-        static_cast<StackAllocator&&>(stack_allocator),-        static_cast<F&&>(function));+        ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+        ASIO_MOVE_CAST(F)(function)); }  template <typename ExecutionContext, typename StackAllocator, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<-        typename ExecutionContext::executor_type>)>>::type) CompletionToken>-inline auto spawn(ExecutionContext& ctx, allocator_arg_t,-    StackAllocator&& stack_allocator, F&& function, CompletionToken&& token,-    constraint_t<+      typename result_of<F(basic_yield_context<+        typename ExecutionContext::executor_type>)>::type>::type)+          CompletionToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<+        typename ExecutionContext::executor_type>)>::type>::type)+spawn(ExecutionContext& ctx, allocator_arg_t,+    ASIO_MOVE_ARG(StackAllocator) stack_allocator,+    ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token,+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    >)-  -> decltype(+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<-          typename ExecutionContext::executor_type>)>>::type>(+        typename result_of<F(basic_yield_context<+          typename ExecutionContext::executor_type>)>::type>::type>(             declval<detail::initiate_spawn<-              typename ExecutionContext::executor_type>>(),+              typename ExecutionContext::executor_type> >(),             token, allocator_arg_t(),-            static_cast<StackAllocator&&>(stack_allocator),-            static_cast<F&&>(function)))+            ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+            ASIO_MOVE_CAST(F)(function)))) {   return (spawn)(ctx.get_executor(), allocator_arg_t(),-      static_cast<StackAllocator&&>(stack_allocator),-      static_cast<F&&>(function), static_cast<CompletionToken&&>(token));+      ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+      ASIO_MOVE_CAST(F)(function),+      ASIO_MOVE_CAST(CompletionToken)(token)); }  template <typename Executor, typename StackAllocator, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type) CompletionToken>-inline auto spawn(const basic_yield_context<Executor>& ctx, allocator_arg_t,-    StackAllocator&& stack_allocator, F&& function, CompletionToken&& token,-    constraint_t<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+        CompletionToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const basic_yield_context<Executor>& ctx, allocator_arg_t,+    ASIO_MOVE_ARG(StackAllocator) stack_allocator,+    ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token,+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    >)-  -> decltype(+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<Executor>)>>::type>(-          declval<detail::initiate_spawn<Executor>>(), token,-          allocator_arg_t(), static_cast<StackAllocator&&>(stack_allocator),-          static_cast<F&&>(function)))+        typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+          declval<detail::initiate_spawn<Executor> >(),+          token, allocator_arg_t(),+          ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+          ASIO_MOVE_CAST(F)(function)))) {   return (spawn)(ctx.get_executor(), allocator_arg_t(),-      static_cast<StackAllocator&&>(stack_allocator),-      static_cast<F&&>(function), static_cast<CompletionToken&&>(token));+      ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+      ASIO_MOVE_CAST(F)(function),+      ASIO_MOVE_CAST(CompletionToken)(token)); }  #endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)++#if defined(ASIO_HAS_BOOST_COROUTINE)++namespace detail {++template <typename Executor, typename Function, typename Handler>+class old_spawn_entry_point+{+public:+  template <typename F, typename H>+  old_spawn_entry_point(const Executor& ex,+      ASIO_MOVE_ARG(F) f, ASIO_MOVE_ARG(H) h)+    : executor_(ex),+      function_(ASIO_MOVE_CAST(F)(f)),+      handler_(ASIO_MOVE_CAST(H)(h))+  {+  }++  void operator()(spawned_thread_base* spawned_thread)+  {+    const basic_yield_context<Executor> yield(spawned_thread, executor_);+    this->call(yield,+        void_type<typename result_of<Function(+          basic_yield_context<Executor>)>::type>());+  }++private:+  void call(const basic_yield_context<Executor>& yield, void_type<void>)+  {+    function_(yield);+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)();+  }++  template <typename T>+  void call(const basic_yield_context<Executor>& yield, void_type<T>)+  {+    ASIO_MOVE_OR_LVALUE(Handler)(handler_)(function_(yield));+  }++  Executor executor_;+  Function function_;+  Handler handler_;+};++inline void default_spawn_handler() {}++} // namespace detail++template <typename Function>+inline void spawn(ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes)+{+  typedef typename decay<Function>::type function_type;++  typename associated_executor<function_type>::type ex(+      (get_associated_executor)(function));++  asio::spawn(ex, ASIO_MOVE_CAST(Function)(function), attributes);+}++template <typename Handler, typename Function>+void spawn(ASIO_MOVE_ARG(Handler) handler,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes,+    typename constraint<+      !is_executor<typename decay<Handler>::type>::value &&+      !execution::is_executor<typename decay<Handler>::type>::value &&+      !is_convertible<Handler&, execution_context&>::value>::type)+{+  typedef typename decay<Handler>::type handler_type;+  typedef typename decay<Function>::type function_type;+  typedef typename associated_executor<handler_type>::type executor_type;++  executor_type ex((get_associated_executor)(handler));++  (dispatch)(ex,+      detail::spawned_thread_resumer(+        detail::spawned_coroutine_thread::spawn(+          detail::old_spawn_entry_point<executor_type,+            function_type, void (*)()>(+              ex, ASIO_MOVE_CAST(Function)(function),+              &detail::default_spawn_handler), attributes)));+}++template <typename Executor, typename Function>+void spawn(basic_yield_context<Executor> ctx,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes)+{+  typedef typename decay<Function>::type function_type;++  (dispatch)(ctx.get_executor(),+      detail::spawned_thread_resumer(+        detail::spawned_coroutine_thread::spawn(+          detail::old_spawn_entry_point<Executor,+            function_type, void (*)()>(ctx.get_executor(),+              ASIO_MOVE_CAST(Function)(function),+              &detail::default_spawn_handler), attributes)));+}++template <typename Function, typename Executor>+inline void spawn(const Executor& ex,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes,+    typename constraint<+      is_executor<Executor>::value || execution::is_executor<Executor>::value+    >::type)+{+  asio::spawn(asio::strand<Executor>(ex),+      ASIO_MOVE_CAST(Function)(function), attributes);+}++template <typename Function, typename Executor>+inline void spawn(const strand<Executor>& ex,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes)+{+  asio::spawn(asio::bind_executor(+        ex, &detail::default_spawn_handler),+      ASIO_MOVE_CAST(Function)(function), attributes);+}++#if !defined(ASIO_NO_TS_EXECUTORS)++template <typename Function>+inline void spawn(const asio::io_context::strand& s,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes)+{+  asio::spawn(asio::bind_executor(+        s, &detail::default_spawn_handler),+      ASIO_MOVE_CAST(Function)(function), attributes);+}++#endif // !defined(ASIO_NO_TS_EXECUTORS)++template <typename Function, typename ExecutionContext>+inline void spawn(ExecutionContext& ctx,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes,+    typename constraint<is_convertible<+      ExecutionContext&, execution_context&>::value>::type)+{+  asio::spawn(ctx.get_executor(),+      ASIO_MOVE_CAST(Function)(function), attributes);+}++#endif // defined(ASIO_HAS_BOOST_COROUTINE)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/impl/src.hpp view
@@ -2,7 +2,7 @@ // impl/src.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,14 +21,13 @@  #include "asio/impl/any_completion_executor.ipp" #include "asio/impl/any_io_executor.ipp"-#include "asio/impl/awaitable.ipp" #include "asio/impl/cancellation_signal.ipp"-#include "asio/impl/config.ipp" #include "asio/impl/connect_pipe.ipp" #include "asio/impl/error.ipp" #include "asio/impl/error_code.ipp" #include "asio/impl/execution_context.ipp" #include "asio/impl/executor.ipp"+#include "asio/impl/handler_alloc_hook.ipp" #include "asio/impl/io_context.ipp" #include "asio/impl/multiple_exceptions.ipp" #include "asio/impl/serial_port_base.ipp"@@ -55,7 +54,6 @@ #include "asio/detail/impl/reactive_descriptor_service.ipp" #include "asio/detail/impl/reactive_socket_service_base.ipp" #include "asio/detail/impl/resolver_service_base.ipp"-#include "asio/detail/impl/resolver_thread_pool.ipp" #include "asio/detail/impl/scheduler.ipp" #include "asio/detail/impl/select_reactor.ipp" #include "asio/detail/impl/service_registry.ipp"@@ -66,6 +64,7 @@ #include "asio/detail/impl/strand_service.ipp" #include "asio/detail/impl/thread_context.ipp" #include "asio/detail/impl/throw_error.ipp"+#include "asio/detail/impl/timer_queue_ptime.ipp" #include "asio/detail/impl/timer_queue_set.ipp" #include "asio/detail/impl/win_iocp_file_service.ipp" #include "asio/detail/impl/win_iocp_handle_service.ipp"@@ -82,6 +81,7 @@ #include "asio/detail/impl/winrt_timer_scheduler.ipp" #include "asio/detail/impl/winsock_init.ipp" #include "asio/execution/impl/bad_executor.ipp"+#include "asio/execution/impl/receiver_invocation_error.ipp" #include "asio/experimental/impl/channel_error.ipp" #include "asio/generic/detail/impl/endpoint.ipp" #include "asio/ip/impl/address.ipp"
link/modules/asio-standalone/asio/include/asio/impl/system_context.hpp view
@@ -2,7 +2,7 @@ // impl/system_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,7 +22,7 @@ namespace asio {  inline system_context::executor_type-system_context::get_executor() noexcept+system_context::get_executor() ASIO_NOEXCEPT {   return system_executor(); }
link/modules/asio-standalone/asio/include/asio/impl/system_context.ipp view
@@ -2,7 +2,7 @@ // impl/system_context.ipp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -45,8 +45,7 @@ };  system_context::system_context()-  : scheduler_(add_scheduler(new detail::scheduler(*this, false))),-    threads_(std::allocator<void>())+  : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false))) {   scheduler_.work_started(); @@ -68,7 +67,7 @@   scheduler_.stop(); } -bool system_context::stopped() const noexcept+bool system_context::stopped() const ASIO_NOEXCEPT {   return scheduler_.stopped(); }
link/modules/asio-standalone/asio/include/asio/impl/system_executor.hpp view
@@ -2,7 +2,7 @@ // impl/system_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -27,7 +27,7 @@ template <typename Blocking, typename Relationship, typename Allocator> inline system_context& basic_system_executor<Blocking, Relationship, Allocator>::query(-    execution::context_t) noexcept+    execution::context_t) ASIO_NOEXCEPT {   return detail::global<system_context>(); }@@ -35,7 +35,7 @@ template <typename Blocking, typename Relationship, typename Allocator> inline std::size_t basic_system_executor<Blocking, Relationship, Allocator>::query(-    execution::occupancy_t) const noexcept+    execution::occupancy_t) const ASIO_NOEXCEPT {   return detail::global<system_context>().num_threads_; }@@ -44,7 +44,7 @@ template <typename Function> inline void basic_system_executor<Blocking, Relationship, Allocator>::do_execute(-    Function&& f, execution::blocking_t::possibly_t) const+    ASIO_MOVE_ARG(Function) f, execution::blocking_t::possibly_t) const {   // Obtain a non-const instance of the function.   detail::non_const_lvalue<Function> f2(f);@@ -54,7 +54,7 @@   { #endif// !defined(ASIO_NO_EXCEPTIONS)     detail::fenced_block b(detail::fenced_block::full);-    static_cast<decay_t<Function>&&>(f2.value)();+    asio_handler_invoke_helpers::invoke(f2.value, f2.value); #if !defined(ASIO_NO_EXCEPTIONS)   }   catch (...)@@ -68,7 +68,7 @@ template <typename Function> inline void basic_system_executor<Blocking, Relationship, Allocator>::do_execute(-    Function&& f, execution::blocking_t::always_t) const+    ASIO_MOVE_ARG(Function) f, execution::blocking_t::always_t) const {   // Obtain a non-const instance of the function.   detail::non_const_lvalue<Function> f2(f);@@ -78,7 +78,7 @@   { #endif// !defined(ASIO_NO_EXCEPTIONS)     detail::fenced_block b(detail::fenced_block::full);-    static_cast<decay_t<Function>&&>(f2.value)();+    asio_handler_invoke_helpers::invoke(f2.value, f2.value); #if !defined(ASIO_NO_EXCEPTIONS)   }   catch (...)@@ -91,15 +91,16 @@ template <typename Blocking, typename Relationship, typename Allocator> template <typename Function> void basic_system_executor<Blocking, Relationship, Allocator>::do_execute(-    Function&& f, execution::blocking_t::never_t) const+    ASIO_MOVE_ARG(Function) f, execution::blocking_t::never_t) const {   system_context& ctx = detail::global<system_context>();    // Allocate and construct an operation to wrap the function.-  typedef detail::executor_op<decay_t<Function>, Allocator> op;+  typedef typename decay<Function>::type function_type;+  typedef detail::executor_op<function_type, Allocator> op;   typename op::ptr p = { detail::addressof(allocator_),       op::ptr::allocate(allocator_), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), allocator_);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), allocator_);    if (is_same<Relationship, execution::relationship_t::continuation_t>::value)   {@@ -120,7 +121,7 @@ #if !defined(ASIO_NO_TS_EXECUTORS) template <typename Blocking, typename Relationship, typename Allocator> inline system_context& basic_system_executor<-    Blocking, Relationship, Allocator>::context() const noexcept+    Blocking, Relationship, Allocator>::context() const ASIO_NOEXCEPT {   return detail::global<system_context>(); }@@ -128,22 +129,25 @@ template <typename Blocking, typename Relationship, typename Allocator> template <typename Function, typename OtherAllocator> void basic_system_executor<Blocking, Relationship, Allocator>::dispatch(-    Function&& f, const OtherAllocator&) const+    ASIO_MOVE_ARG(Function) f, const OtherAllocator&) const {-  decay_t<Function>(static_cast<Function&&>(f))();+  typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));+  asio_handler_invoke_helpers::invoke(tmp, tmp); }  template <typename Blocking, typename Relationship, typename Allocator> template <typename Function, typename OtherAllocator> void basic_system_executor<Blocking, Relationship, Allocator>::post(-    Function&& f, const OtherAllocator& a) const+    ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {+  typedef typename decay<Function>::type function_type;+   system_context& ctx = detail::global<system_context>();    // Allocate and construct an operation to wrap the function.-  typedef detail::executor_op<decay_t<Function>, OtherAllocator> op;+  typedef detail::executor_op<function_type, OtherAllocator> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);    ASIO_HANDLER_CREATION((ctx, *p.p,         "system_executor", &this->context(), 0, "post"));@@ -155,14 +159,16 @@ template <typename Blocking, typename Relationship, typename Allocator> template <typename Function, typename OtherAllocator> void basic_system_executor<Blocking, Relationship, Allocator>::defer(-    Function&& f, const OtherAllocator& a) const+    ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {+  typedef typename decay<Function>::type function_type;+   system_context& ctx = detail::global<system_context>();    // Allocate and construct an operation to wrap the function.-  typedef detail::executor_op<decay_t<Function>, OtherAllocator> op;+  typedef detail::executor_op<function_type, OtherAllocator> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);    ASIO_HANDLER_CREATION((ctx, *p.p,         "system_executor", &this->context(), 0, "defer"));
link/modules/asio-standalone/asio/include/asio/impl/thread_pool.hpp view
@@ -2,7 +2,7 @@ // impl/thread_pool.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -15,8 +15,8 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include "asio/config.hpp" #include "asio/detail/blocking_executor_op.hpp"+#include "asio/detail/bulk_executor_op.hpp" #include "asio/detail/executor_op.hpp" #include "asio/detail/fenced_block.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -27,63 +27,28 @@  namespace asio { -#if !defined(ASIO_NO_TS_EXECUTORS)--template <typename Allocator>-thread_pool::thread_pool(allocator_arg_t, const Allocator& a)-  : execution_context(std::allocator_arg, a),-    scheduler_(asio::make_service<detail::scheduler>(*this, false)),-    threads_(allocator<void>(*this)),-    num_threads_(default_thread_pool_size()),-    joinable_(true)-{-  start();-}--#endif // !defined(ASIO_NO_TS_EXECUTORS)--template <typename Allocator>-thread_pool::thread_pool(allocator_arg_t,-    const Allocator& a, std::size_t num_threads)-  : execution_context(std::allocator_arg, a,-      config_from_concurrency_hint(num_threads == 1 ? 1 : 0)),-    scheduler_(asio::make_service<detail::scheduler>(*this, false)),-    threads_(allocator<void>(*this)),-    num_threads_(clamp_thread_pool_size(num_threads)),-    joinable_(true)-{-  start();-}--template <typename Allocator>-thread_pool::thread_pool(allocator_arg_t,-    const Allocator& a, std::size_t num_threads,-    const execution_context::service_maker& initial_services)-  : execution_context(std::allocator_arg, a, initial_services),-    scheduler_(asio::make_service<detail::scheduler>(*this, false)),-    threads_(allocator<void>(*this)),-    num_threads_(clamp_thread_pool_size(num_threads)),-    joinable_(true)+inline thread_pool::executor_type+thread_pool::get_executor() ASIO_NOEXCEPT {-  start();+  return executor_type(*this); }  inline thread_pool::executor_type-thread_pool::get_executor() noexcept+thread_pool::executor() ASIO_NOEXCEPT {   return executor_type(*this); } -inline thread_pool::executor_type-thread_pool::executor() noexcept+inline thread_pool::scheduler_type+thread_pool::scheduler() ASIO_NOEXCEPT {-  return executor_type(*this);+  return scheduler_type(*this); }  template <typename Allocator, unsigned int Bits> thread_pool::basic_executor_type<Allocator, Bits>& thread_pool::basic_executor_type<Allocator, Bits>::operator=(-    const basic_executor_type& other) noexcept+    const basic_executor_type& other) ASIO_NOEXCEPT {   if (this != &other)   {@@ -102,10 +67,11 @@   return *this; } +#if defined(ASIO_HAS_MOVE) template <typename Allocator, unsigned int Bits> thread_pool::basic_executor_type<Allocator, Bits>& thread_pool::basic_executor_type<Allocator, Bits>::operator=(-    basic_executor_type&& other) noexcept+    basic_executor_type&& other) ASIO_NOEXCEPT {   if (this != &other)   {@@ -122,10 +88,11 @@   }   return *this; }+#endif // defined(ASIO_HAS_MOVE)  template <typename Allocator, unsigned int Bits> inline bool thread_pool::basic_executor_type<Allocator,-    Bits>::running_in_this_thread() const noexcept+    Bits>::running_in_this_thread() const ASIO_NOEXCEPT {   return pool_->scheduler_.can_dispatch(); }@@ -133,39 +100,43 @@ template <typename Allocator, unsigned int Bits> template <typename Function> void thread_pool::basic_executor_type<Allocator,-    Bits>::do_execute(Function&& f, false_type) const+    Bits>::do_execute(ASIO_MOVE_ARG(Function) f, false_type) const {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // Invoke immediately if the blocking.possibly property is enabled and we are   // already inside the thread pool.   if ((bits_ & blocking_never) == 0 && pool_->scheduler_.can_dispatch())   {     // Make a local, non-const copy of the function.-    function_type tmp(static_cast<Function&&>(f));+    function_type tmp(ASIO_MOVE_CAST(Function)(f)); -#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  && !defined(ASIO_NO_EXCEPTIONS)     try     {-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       //   && !defined(ASIO_NO_EXCEPTIONS)       detail::fenced_block b(detail::fenced_block::full);-      static_cast<function_type&&>(tmp)();+      asio_handler_invoke_helpers::invoke(tmp, tmp);       return;-#if !defined(ASIO_NO_EXCEPTIONS)+#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  && !defined(ASIO_NO_EXCEPTIONS)     }     catch (...)     {       pool_->scheduler_.capture_current_exception();       return;     }-#endif // !defined(ASIO_NO_EXCEPTIONS)+#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       //   && !defined(ASIO_NO_EXCEPTIONS)   }    // Allocate and construct an operation to wrap the function.   typedef detail::executor_op<function_type, Allocator> op;   typename op::ptr p = { detail::addressof(allocator_),       op::ptr::allocate(allocator_), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), allocator_);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), allocator_);    if ((bits_ & relationship_continuation) != 0)   {@@ -186,7 +157,7 @@ template <typename Allocator, unsigned int Bits> template <typename Function> void thread_pool::basic_executor_type<Allocator,-    Bits>::do_execute(Function&& f, true_type) const+    Bits>::do_execute(ASIO_MOVE_ARG(Function) f, true_type) const {   // Obtain a non-const instance of the function.   detail::non_const_lvalue<Function> f2(f);@@ -199,7 +170,7 @@     { #endif // !defined(ASIO_NO_EXCEPTIONS)       detail::fenced_block b(detail::fenced_block::full);-      static_cast<decay_t<Function>&&>(f2.value)();+      asio_handler_invoke_helpers::invoke(f2.value, f2.value);       return; #if !defined(ASIO_NO_EXCEPTIONS)     }@@ -211,7 +182,7 @@   }    // Construct an operation to wrap the function.-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;   detail::blocking_executor_op<function_type> op(f2.value);    ASIO_HANDLER_CREATION((*pool_, op,@@ -221,24 +192,88 @@   op.wait(); } +template <typename Allocator, unsigned int Bits>+template <typename Function>+void thread_pool::basic_executor_type<Allocator, Bits>::do_bulk_execute(+    ASIO_MOVE_ARG(Function) f, std::size_t n, false_type) const+{+  typedef typename decay<Function>::type function_type;+  typedef detail::bulk_executor_op<function_type, Allocator> op;++  // Allocate and construct operations to wrap the function.+  detail::op_queue<detail::scheduler_operation> ops;+  for (std::size_t i = 0; i < n; ++i)+  {+    typename op::ptr p = { detail::addressof(allocator_),+        op::ptr::allocate(allocator_), 0 };+    p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), allocator_, i);+    ops.push(p.p);++    if ((bits_ & relationship_continuation) != 0)+    {+      ASIO_HANDLER_CREATION((*pool_, *p.p,+            "thread_pool", pool_, 0, "bulk_execute(blk=never,rel=cont)"));+    }+    else+    {+      ASIO_HANDLER_CREATION((*pool_, *p.p,+            "thread_pool", pool_, 0, "bulk)execute(blk=never,rel=fork)"));+    }++    p.v = p.p = 0;+  }++  pool_->scheduler_.post_immediate_completions(n,+      ops, (bits_ & relationship_continuation) != 0);+}++template <typename Function>+struct thread_pool_always_blocking_function_adapter+{+  typename decay<Function>::type* f;+  std::size_t n;++  void operator()()+  {+    for (std::size_t i = 0; i < n; ++i)+    {+      (*f)(i);+    }+  }+};++template <typename Allocator, unsigned int Bits>+template <typename Function>+void thread_pool::basic_executor_type<Allocator, Bits>::do_bulk_execute(+    ASIO_MOVE_ARG(Function) f, std::size_t n, true_type) const+{+  // Obtain a non-const instance of the function.+  detail::non_const_lvalue<Function> f2(f);++  thread_pool_always_blocking_function_adapter<Function>+    adapter = { detail::addressof(f2.value), n };++  this->do_execute(adapter, true_type());+}+ #if !defined(ASIO_NO_TS_EXECUTORS) template <typename Allocator, unsigned int Bits> inline thread_pool& thread_pool::basic_executor_type<-    Allocator, Bits>::context() const noexcept+    Allocator, Bits>::context() const ASIO_NOEXCEPT {   return *pool_; }  template <typename Allocator, unsigned int Bits> inline void thread_pool::basic_executor_type<Allocator,-    Bits>::on_work_started() const noexcept+    Bits>::on_work_started() const ASIO_NOEXCEPT {   pool_->scheduler_.work_started(); }  template <typename Allocator, unsigned int Bits> inline void thread_pool::basic_executor_type<Allocator,-    Bits>::on_work_finished() const noexcept+    Bits>::on_work_finished() const ASIO_NOEXCEPT {   pool_->scheduler_.work_finished(); }@@ -246,25 +281,25 @@ template <typename Allocator, unsigned int Bits> template <typename Function, typename OtherAllocator> void thread_pool::basic_executor_type<Allocator, Bits>::dispatch(-    Function&& f, const OtherAllocator& a) const+    ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // Invoke immediately if we are already inside the thread pool.   if (pool_->scheduler_.can_dispatch())   {     // Make a local, non-const copy of the function.-    function_type tmp(static_cast<Function&&>(f));+    function_type tmp(ASIO_MOVE_CAST(Function)(f));      detail::fenced_block b(detail::fenced_block::full);-    static_cast<function_type&&>(tmp)();+    asio_handler_invoke_helpers::invoke(tmp, tmp);     return;   }    // Allocate and construct an operation to wrap the function.   typedef detail::executor_op<function_type, OtherAllocator> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);    ASIO_HANDLER_CREATION((*pool_, *p.p,         "thread_pool", pool_, 0, "dispatch"));@@ -276,14 +311,14 @@ template <typename Allocator, unsigned int Bits> template <typename Function, typename OtherAllocator> void thread_pool::basic_executor_type<Allocator, Bits>::post(-    Function&& f, const OtherAllocator& a) const+    ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // Allocate and construct an operation to wrap the function.   typedef detail::executor_op<function_type, OtherAllocator> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);    ASIO_HANDLER_CREATION((*pool_, *p.p,         "thread_pool", pool_, 0, "post"));@@ -295,14 +330,14 @@ template <typename Allocator, unsigned int Bits> template <typename Function, typename OtherAllocator> void thread_pool::basic_executor_type<Allocator, Bits>::defer(-    Function&& f, const OtherAllocator& a) const+    ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const {-  typedef decay_t<Function> function_type;+  typedef typename decay<Function>::type function_type;    // Allocate and construct an operation to wrap the function.   typedef detail::executor_op<function_type, OtherAllocator> op;   typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };-  p.p = new (p.v) op(static_cast<Function&&>(f), a);+  p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);    ASIO_HANDLER_CREATION((*pool_, *p.p,         "thread_pool", pool_, 0, "defer"));
link/modules/asio-standalone/asio/include/asio/impl/thread_pool.ipp view
@@ -2,7 +2,7 @@ // impl/thread_pool.ipp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -47,26 +47,31 @@ };  #if !defined(ASIO_NO_TS_EXECUTORS)+namespace detail { -long thread_pool::default_thread_pool_size()+inline long default_thread_pool_size() {-  std::size_t num_threads = detail::thread::hardware_concurrency() * 2;+  std::size_t num_threads = thread::hardware_concurrency() * 2;   num_threads = num_threads == 0 ? 2 : num_threads;   return static_cast<long>(num_threads); } +} // namespace detail+ thread_pool::thread_pool()-  : scheduler_(asio::make_service<detail::scheduler>(*this, false)),-    threads_(allocator<void>(*this)),-    num_threads_(default_thread_pool_size()),-    joinable_(true)+  : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false))),+    num_threads_(detail::default_thread_pool_size()) {-  start();-}+  scheduler_.work_started(); +  thread_function f = { &scheduler_ };+  threads_.create_threads(f, static_cast<std::size_t>(num_threads_));+} #endif // !defined(ASIO_NO_TS_EXECUTORS) -long thread_pool::clamp_thread_pool_size(std::size_t n)+namespace detail {++inline long clamp_thread_pool_size(std::size_t n) {   if (n > 0x7FFFFFFF)   {@@ -76,25 +81,17 @@   return static_cast<long>(n & 0x7FFFFFFF); } +} // namespace detail+ thread_pool::thread_pool(std::size_t num_threads)-  : execution_context(config_from_concurrency_hint(num_threads == 1 ? 1 : 0)),-    scheduler_(asio::make_service<detail::scheduler>(*this, false)),-    threads_(allocator<void>(*this)),-    num_threads_(clamp_thread_pool_size(num_threads)),-    joinable_(true)+  : scheduler_(add_scheduler(new detail::scheduler(+          *this, num_threads == 1 ? 1 : 0, false))),+    num_threads_(detail::clamp_thread_pool_size(num_threads)) {-  start();-}+  scheduler_.work_started(); -thread_pool::thread_pool(std::size_t num_threads,-    const execution_context::service_maker& initial_services)-  : execution_context(initial_services),-    scheduler_(asio::make_service<detail::scheduler>(*this, false)),-    threads_(allocator<void>(*this)),-    num_threads_(clamp_thread_pool_size(num_threads)),-    joinable_(true)-{-  start();+  thread_function f = { &scheduler_ };+  threads_.create_threads(f, static_cast<std::size_t>(num_threads_)); }  thread_pool::~thread_pool()@@ -104,13 +101,6 @@   shutdown(); } -void thread_pool::start()-{-  scheduler_.work_started();-  thread_function f = { &scheduler_ };-  threads_.create_threads(f, static_cast<std::size_t>(num_threads_));-}- void thread_pool::stop() {   scheduler_.stop();@@ -125,17 +115,24 @@  void thread_pool::join() {-  if (joinable_)-  {-    joinable_ = false;+  if (num_threads_)     scheduler_.work_finished();++  if (!threads_.empty())     threads_.join();-  } } +detail::scheduler& thread_pool::add_scheduler(detail::scheduler* s)+{+  detail::scoped_ptr<detail::scheduler> scoped_impl(s);+  asio::add_service<detail::scheduler>(*this, scoped_impl.get());+  return *scoped_impl.release();+}+ void thread_pool::wait() {-  join();+  scheduler_.work_finished();+  threads_.join(); }  } // namespace asio
link/modules/asio-standalone/asio/include/asio/impl/use_awaitable.hpp view
@@ -2,7 +2,7 @@ // impl/use_awaitable.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,7 +18,6 @@ #include "asio/detail/config.hpp" #include "asio/async_result.hpp" #include "asio/cancellation_signal.hpp"-#include "asio/disposition.hpp"  #include "asio/detail/push_options.hpp" @@ -74,27 +73,77 @@   } }; +template <typename Executor>+class awaitable_handler<Executor, asio::error_code>+  : public awaitable_handler_base<Executor, void>+{+public:+  using awaitable_handler_base<Executor, void>::awaitable_handler_base;++  void operator()(const asio::error_code& ec)+  {+    this->frame()->attach_thread(this);+    if (ec)+      this->frame()->set_error(ec);+    else+      this->frame()->return_void();+    this->frame()->clear_cancellation_slot();+    this->frame()->pop_frame();+    this->pump();+  }+};++template <typename Executor>+class awaitable_handler<Executor, std::exception_ptr>+  : public awaitable_handler_base<Executor, void>+{+public:+  using awaitable_handler_base<Executor, void>::awaitable_handler_base;++  void operator()(std::exception_ptr ex)+  {+    this->frame()->attach_thread(this);+    if (ex)+      this->frame()->set_except(ex);+    else+      this->frame()->return_void();+    this->frame()->clear_cancellation_slot();+    this->frame()->pop_frame();+    this->pump();+  }+};+ template <typename Executor, typename T> class awaitable_handler<Executor, T>-  : public awaitable_handler_base<Executor,-      conditional_t<is_disposition<T>::value, void, T>>+  : public awaitable_handler_base<Executor, T> { public:-  using awaitable_handler_base<Executor,-    conditional_t<is_disposition<T>::value, void, T>>-      ::awaitable_handler_base;+  using awaitable_handler_base<Executor, T>::awaitable_handler_base;    template <typename Arg>   void operator()(Arg&& arg)   {     this->frame()->attach_thread(this);-    if constexpr (is_disposition<T>::value)-    {-      if (arg == no_error)-        this->frame()->return_void();-      else-        this->frame()->set_disposition(arg);-    }+    this->frame()->return_value(std::forward<Arg>(arg));+    this->frame()->clear_cancellation_slot();+    this->frame()->pop_frame();+    this->pump();+  }+};++template <typename Executor, typename T>+class awaitable_handler<Executor, asio::error_code, T>+  : public awaitable_handler_base<Executor, T>+{+public:+  using awaitable_handler_base<Executor, T>::awaitable_handler_base;++  template <typename Arg>+  void operator()(const asio::error_code& ec, Arg&& arg)+  {+    this->frame()->attach_thread(this);+    if (ec)+      this->frame()->set_error(ec);     else       this->frame()->return_value(std::forward<Arg>(arg));     this->frame()->clear_cancellation_slot();@@ -103,66 +152,84 @@   } }; -template <typename Executor, typename T0, typename T1>-class awaitable_handler<Executor, T0, T1>-  : public awaitable_handler_base<Executor,-      conditional_t<is_disposition<T0>::value, T1, std::tuple<T0, T1>>>+template <typename Executor, typename T>+class awaitable_handler<Executor, std::exception_ptr, T>+  : public awaitable_handler_base<Executor, T> { public:+  using awaitable_handler_base<Executor, T>::awaitable_handler_base;++  template <typename Arg>+  void operator()(std::exception_ptr ex, Arg&& arg)+  {+    this->frame()->attach_thread(this);+    if (ex)+      this->frame()->set_except(ex);+    else+      this->frame()->return_value(std::forward<Arg>(arg));+    this->frame()->clear_cancellation_slot();+    this->frame()->pop_frame();+    this->pump();+  }+};++template <typename Executor, typename... Ts>+class awaitable_handler+  : public awaitable_handler_base<Executor, std::tuple<Ts...>>+{+public:   using awaitable_handler_base<Executor,-    conditional_t<is_disposition<T0>::value, T1, std::tuple<T0, T1>>>-      ::awaitable_handler_base;+    std::tuple<Ts...>>::awaitable_handler_base; -  template <typename Arg0, typename Arg1>-  void operator()(Arg0&& arg0, Arg1&& arg1)+  template <typename... Args>+  void operator()(Args&&... args)   {     this->frame()->attach_thread(this);-    if constexpr (is_disposition<T0>::value)-    {-      if (arg0 == no_error)-        this->frame()->return_value(std::forward<Arg1>(arg1));-      else-        this->frame()->set_disposition(std::forward<Arg0>(arg0));-    }+    this->frame()->return_values(std::forward<Args>(args)...);+    this->frame()->clear_cancellation_slot();+    this->frame()->pop_frame();+    this->pump();+  }+};++template <typename Executor, typename... Ts>+class awaitable_handler<Executor, asio::error_code, Ts...>+  : public awaitable_handler_base<Executor, std::tuple<Ts...>>+{+public:+  using awaitable_handler_base<Executor,+    std::tuple<Ts...>>::awaitable_handler_base;++  template <typename... Args>+  void operator()(const asio::error_code& ec, Args&&... args)+  {+    this->frame()->attach_thread(this);+    if (ec)+      this->frame()->set_error(ec);     else-    {-      this->frame()->return_values(std::forward<Arg0>(arg0),-          std::forward<Arg1>(arg1));-    }+      this->frame()->return_values(std::forward<Args>(args)...);     this->frame()->clear_cancellation_slot();     this->frame()->pop_frame();     this->pump();   } }; -template <typename Executor, typename T0, typename... Ts>-class awaitable_handler<Executor, T0, Ts...>-  : public awaitable_handler_base<Executor,-      conditional_t<is_disposition<T0>::value,-        std::tuple<Ts...>, std::tuple<T0, Ts...>>>+template <typename Executor, typename... Ts>+class awaitable_handler<Executor, std::exception_ptr, Ts...>+  : public awaitable_handler_base<Executor, std::tuple<Ts...>> { public:   using awaitable_handler_base<Executor,-      conditional_t<is_disposition<T0>::value,-        std::tuple<Ts...>, std::tuple<T0, Ts...>>>-          ::awaitable_handler_base;+    std::tuple<Ts...>>::awaitable_handler_base; -  template <typename Arg0, typename... Args>-  void operator()(Arg0&& arg0, Args&&... args)+  template <typename... Args>+  void operator()(std::exception_ptr ex, Args&&... args)   {     this->frame()->attach_thread(this);-    if constexpr (is_disposition<T0>::value)-    {-      if (arg0 == no_error)-        this->frame()->return_values(std::forward<Args>(args)...);-      else-        this->frame()->set_disposition(std::forward<Arg0>(arg0));-    }+    if (ex)+      this->frame()->set_except(ex);     else-    {-      this->frame()->return_values(std::forward<Arg0>(arg0),-          std::forward<Args>(args)...);-    }+      this->frame()->return_values(std::forward<Args>(args)...);     this->frame()->clear_cancellation_slot();     this->frame()->pop_frame();     this->pump();@@ -191,7 +258,7 @@ { public:   typedef typename detail::awaitable_handler<-      Executor, decay_t<Args>...> handler_type;+      Executor, typename decay<Args>::type...> handler_type;   typedef typename handler_type::awaitable_type return_type;    template <typename Initiation, typename... InitArgs>@@ -219,9 +286,9 @@       };      for (;;) {} // Never reached.-#if defined(_MSC_VER) && !defined(__clang__)+#if defined(_MSC_VER)     co_return dummy_return<typename return_type::value_type>();-#endif // defined(_MSC_VER) && !defined(__clang__)+#endif // defined(_MSC_VER)   } }; 
link/modules/asio-standalone/asio/include/asio/impl/use_future.hpp view
@@ -2,7 +2,7 @@ // impl/use_future.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,9 +19,8 @@ #include <tuple> #include "asio/async_result.hpp" #include "asio/detail/memory.hpp"-#include "asio/detail/type_traits.hpp" #include "asio/dispatch.hpp"-#include "asio/disposition.hpp"+#include "asio/error_code.hpp" #include "asio/execution.hpp" #include "asio/packaged_task.hpp" #include "asio/system_error.hpp"@@ -32,15 +31,17 @@ namespace asio { namespace detail { +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename F, typename... Args> inline void promise_invoke_and_set(std::promise<T>& p,-    F& f, Args&&... args)+    F& f, ASIO_MOVE_ARG(Args)... args) { #if !defined(ASIO_NO_EXCEPTIONS)   try #endif // !defined(ASIO_NO_EXCEPTIONS)   {-    p.set_value(f(static_cast<Args&&>(args)...));+    p.set_value(f(ASIO_MOVE_CAST(Args)(args)...));   } #if !defined(ASIO_NO_EXCEPTIONS)   catch (...)@@ -52,13 +53,13 @@  template <typename F, typename... Args> inline void promise_invoke_and_set(std::promise<void>& p,-    F& f, Args&&... args)+    F& f, ASIO_MOVE_ARG(Args)... args) { #if !defined(ASIO_NO_EXCEPTIONS)   try #endif // !defined(ASIO_NO_EXCEPTIONS)   {-    f(static_cast<Args&&>(args)...);+    f(ASIO_MOVE_CAST(Args)(args)...);     p.set_value();   } #if !defined(ASIO_NO_EXCEPTIONS)@@ -69,15 +70,112 @@ #endif // !defined(ASIO_NO_EXCEPTIONS) } +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename F>+inline void promise_invoke_and_set(std::promise<T>& p, F& f)+{+#if !defined(ASIO_NO_EXCEPTIONS)+  try+#endif // !defined(ASIO_NO_EXCEPTIONS)+  {+    p.set_value(f());+  }+#if !defined(ASIO_NO_EXCEPTIONS)+  catch (...)+  {+    p.set_exception(std::current_exception());+  }+#endif // !defined(ASIO_NO_EXCEPTIONS)+}++template <typename F, typename Args>+inline void promise_invoke_and_set(std::promise<void>& p, F& f)+{+#if !defined(ASIO_NO_EXCEPTIONS)+  try+#endif // !defined(ASIO_NO_EXCEPTIONS)+  {+    f();+    p.set_value();+#if !defined(ASIO_NO_EXCEPTIONS)+  }+  catch (...)+  {+    p.set_exception(std::current_exception());+  }+#endif // !defined(ASIO_NO_EXCEPTIONS)+}++#if defined(ASIO_NO_EXCEPTIONS)++#define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \+  template <typename T, typename F, ASIO_VARIADIC_TPARAMS(n)> \+  inline void promise_invoke_and_set(std::promise<T>& p, \+      F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \+  } \+  \+  template <typename F, ASIO_VARIADIC_TPARAMS(n)> \+  inline void promise_invoke_and_set(std::promise<void>& p, \+      F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    f(ASIO_VARIADIC_MOVE_ARGS(n)); \+    p.set_value(); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF)+#undef ASIO_PRIVATE_PROMISE_INVOKE_DEF++#else // defined(ASIO_NO_EXCEPTIONS)++#define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \+  template <typename T, typename F, ASIO_VARIADIC_TPARAMS(n)> \+  inline void promise_invoke_and_set(std::promise<T>& p, \+      F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    try \+    { \+      p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \+    } \+    catch (...) \+    { \+      p.set_exception(std::current_exception()); \+    } \+  } \+  \+  template <typename F, ASIO_VARIADIC_TPARAMS(n)> \+  inline void promise_invoke_and_set(std::promise<void>& p, \+      F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \+  { \+    try \+    { \+      f(ASIO_VARIADIC_MOVE_ARGS(n)); \+      p.set_value(); \+    } \+    catch (...) \+    { \+      p.set_exception(std::current_exception()); \+    } \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF)+#undef ASIO_PRIVATE_PROMISE_INVOKE_DEF++#endif // defined(ASIO_NO_EXCEPTIONS)++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // A function object adapter to invoke a nullary function object and capture // any exception thrown into a promise. template <typename T, typename F> class promise_invoker { public:-  promise_invoker(const shared_ptr<std::promise<T>>& p,-      F&& f)-    : p_(p), f_(static_cast<F&&>(f))+  promise_invoker(const shared_ptr<std::promise<T> >& p,+      ASIO_MOVE_ARG(F) f)+    : p_(p), f_(ASIO_MOVE_CAST(F)(f))   {   } @@ -98,27 +196,27 @@   }  private:-  shared_ptr<std::promise<T>> p_;-  decay_t<F> f_;+  shared_ptr<std::promise<T> > p_;+  typename decay<F>::type f_; }; -// An executor that adapts the system_executor to capture any exception thrown+// An executor that adapts the system_executor to capture any exeption thrown // by a submitted function object and save it into a promise. template <typename T, typename Blocking = execution::blocking_t::possibly_t> class promise_executor { public:-  explicit promise_executor(const shared_ptr<std::promise<T>>& p)+  explicit promise_executor(const shared_ptr<std::promise<T> >& p)     : p_(p)   {   } -  execution_context& query(execution::context_t) const noexcept+  execution_context& query(execution::context_t) const ASIO_NOEXCEPT   {     return asio::query(system_executor(), execution::context);   } -  static constexpr Blocking query(execution::blocking_t)+  static ASIO_CONSTEXPR Blocking query(execution::blocking_t)   {     return Blocking();   }@@ -136,56 +234,62 @@   }    template <typename F>-  void execute(F&& f) const+  void execute(ASIO_MOVE_ARG(F) f) const   {+#if defined(ASIO_NO_DEPRECATED)     asio::require(system_executor(), Blocking()).execute(-        promise_invoker<T, F>(p_, static_cast<F&&>(f)));+        promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)));+#else // defined(ASIO_NO_DEPRECATED)+    execution::execute(+        asio::require(system_executor(), Blocking()),+        promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)));+#endif // defined(ASIO_NO_DEPRECATED)   }  #if !defined(ASIO_NO_TS_EXECUTORS)-  execution_context& context() const noexcept+  execution_context& context() const ASIO_NOEXCEPT   {     return system_executor().context();   } -  void on_work_started() const noexcept {}-  void on_work_finished() const noexcept {}+  void on_work_started() const ASIO_NOEXCEPT {}+  void on_work_finished() const ASIO_NOEXCEPT {}    template <typename F, typename A>-  void dispatch(F&& f, const A&) const+  void dispatch(ASIO_MOVE_ARG(F) f, const A&) const   {-    promise_invoker<T, F>(p_, static_cast<F&&>(f))();+    promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f))();   }    template <typename F, typename A>-  void post(F&& f, const A& a) const+  void post(ASIO_MOVE_ARG(F) f, const A& a) const   {     system_executor().post(-        promise_invoker<T, F>(p_, static_cast<F&&>(f)), a);+        promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)), a);   }    template <typename F, typename A>-  void defer(F&& f, const A& a) const+  void defer(ASIO_MOVE_ARG(F) f, const A& a) const   {     system_executor().defer(-        promise_invoker<T, F>(p_, static_cast<F&&>(f)), a);+        promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)), a);   } #endif // !defined(ASIO_NO_TS_EXECUTORS)    friend bool operator==(const promise_executor& a,-      const promise_executor& b) noexcept+      const promise_executor& b) ASIO_NOEXCEPT   {     return a.p_ == b.p_;   }    friend bool operator!=(const promise_executor& a,-      const promise_executor& b) noexcept+      const promise_executor& b) ASIO_NOEXCEPT   {     return a.p_ != b.p_;   }  private:-  shared_ptr<std::promise<T>> p_;+  shared_ptr<std::promise<T> > p_; };  // The base class for all completion handlers that create promises.@@ -195,7 +299,7 @@ public:   typedef promise_executor<T> executor_type; -  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return executor_type(p_);   }@@ -215,7 +319,7 @@     p_ = std::allocate_shared<std::promise<T>>(b, std::allocator_arg, b);   } -  shared_ptr<std::promise<T>> p_;+  shared_ptr<std::promise<T> > p_; };  // For completion signature void().@@ -229,18 +333,18 @@   } }; -// For completion signature void(disposition auto).-template <typename Disposition>-class promise_handler_d_0+// For completion signature void(error_code).+class promise_handler_ec_0   : public promise_creator<void> { public:-  void operator()(Disposition d)+  void operator()(const asio::error_code& ec)   {-    if (d != no_error)+    if (ec)     {       this->p_->set_exception(-          (to_exception_ptr)(static_cast<Disposition&&>(d)));+          std::make_exception_ptr(+            asio::system_error(ec)));     }     else     {@@ -249,6 +353,24 @@   } }; +// For completion signature void(exception_ptr).+class promise_handler_ex_0+  : public promise_creator<void>+{+public:+  void operator()(const std::exception_ptr& ex)+  {+    if (ex)+    {+      this->p_->set_exception(ex);+    }+    else+    {+      this->p_->set_value();+    }+  }+};+ // For completion signature void(T). template <typename T> class promise_handler_1@@ -256,102 +378,249 @@ { public:   template <typename Arg>-  void operator()(Arg&& arg)+  void operator()(ASIO_MOVE_ARG(Arg) arg)   {-    this->p_->set_value(static_cast<Arg&&>(arg));+    this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg));   } }; -// For completion signature void(disposition auto, T).-template <typename Disposition, typename T>-class promise_handler_d_1+// For completion signature void(error_code, T).+template <typename T>+class promise_handler_ec_1   : public promise_creator<T> { public:   template <typename Arg>-  void operator()(Disposition d, Arg&& arg)+  void operator()(const asio::error_code& ec,+      ASIO_MOVE_ARG(Arg) arg)   {-    if (d != no_error)+    if (ec)     {       this->p_->set_exception(-          (to_exception_ptr)(static_cast<Disposition&&>(d)));+          std::make_exception_ptr(+            asio::system_error(ec)));     }     else-      this->p_->set_value(static_cast<Arg&&>(arg));+      this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg));   } }; +// For completion signature void(exception_ptr, T).+template <typename T>+class promise_handler_ex_1+  : public promise_creator<T>+{+public:+  template <typename Arg>+  void operator()(const std::exception_ptr& ex,+      ASIO_MOVE_ARG(Arg) arg)+  {+    if (ex)+      this->p_->set_exception(ex);+    else+      this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg));+  }+};+ // For completion signature void(T1, ..., Tn); template <typename T> class promise_handler_n   : public promise_creator<T> { public:+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename... Args>-  void operator()(Args&&... args)+  void operator()(ASIO_MOVE_ARG(Args)... args)   {     this->p_->set_value(         std::forward_as_tuple(-          static_cast<Args&&>(args)...));+          ASIO_MOVE_CAST(Args)(args)...));   }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_CALL_OP_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \+  {\+    this->p_->set_value( \+        std::forward_as_tuple( \+          ASIO_VARIADIC_MOVE_ARGS(n))); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF)+#undef ASIO_PRIVATE_CALL_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) };  // For completion signature void(error_code, T1, ..., Tn);-template <typename Disposition, typename T>-class promise_handler_d_n+template <typename T>+class promise_handler_ec_n   : public promise_creator<T> { public:+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename... Args>-  void operator()(Disposition d, Args&&... args)+  void operator()(const asio::error_code& ec,+      ASIO_MOVE_ARG(Args)... args)   {-    if (d != no_error)+    if (ec)     {       this->p_->set_exception(-          (to_exception_ptr)(static_cast<Disposition&&>(d)));+          std::make_exception_ptr(+            asio::system_error(ec)));     }     else     {       this->p_->set_value(           std::forward_as_tuple(-            static_cast<Args&&>(args)...));+            ASIO_MOVE_CAST(Args)(args)...));     }   }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_CALL_OP_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  void operator()(const asio::error_code& ec, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  {\+    if (ec) \+    { \+      this->p_->set_exception( \+          std::make_exception_ptr( \+            asio::system_error(ec))); \+    } \+    else \+    { \+      this->p_->set_value( \+          std::forward_as_tuple( \+            ASIO_VARIADIC_MOVE_ARGS(n))); \+    } \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF)+#undef ASIO_PRIVATE_CALL_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) }; +// For completion signature void(exception_ptr, T1, ..., Tn);+template <typename T>+class promise_handler_ex_n+  : public promise_creator<T>+{+public:+#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++  template <typename... Args>+  void operator()(const std::exception_ptr& ex,+      ASIO_MOVE_ARG(Args)... args)+  {+    if (ex)+      this->p_->set_exception(ex);+    else+    {+      this->p_->set_value(+          std::forward_as_tuple(+            ASIO_MOVE_CAST(Args)(args)...));+    }+  }++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_CALL_OP_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  void operator()(const std::exception_ptr& ex, \+      ASIO_VARIADIC_MOVE_PARAMS(n)) \+  {\+    if (ex) \+      this->p_->set_exception(ex); \+    else \+    { \+      this->p_->set_value( \+          std::forward_as_tuple( \+            ASIO_VARIADIC_MOVE_ARGS(n))); \+    } \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF)+#undef ASIO_PRIVATE_CALL_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+};+ // Helper template to choose the appropriate concrete promise handler // implementation based on the supplied completion signature.-template <typename, typename = void> class promise_handler_selector;+template <typename> class promise_handler_selector;  template <> class promise_handler_selector<void()>   : public promise_handler_0 {}; +template <>+class promise_handler_selector<void(asio::error_code)>+  : public promise_handler_ec_0 {};++template <>+class promise_handler_selector<void(std::exception_ptr)>+  : public promise_handler_ex_0 {};+ template <typename Arg>-class promise_handler_selector<void(Arg),-  enable_if_t<is_disposition<Arg>::value>>-    : public promise_handler_d_0<Arg> {};+class promise_handler_selector<void(Arg)>+  : public promise_handler_1<Arg> {};  template <typename Arg>-class promise_handler_selector<void(Arg),-  enable_if_t<!is_disposition<Arg>::value>>-    : public promise_handler_1<Arg> {};+class promise_handler_selector<void(asio::error_code, Arg)>+  : public promise_handler_ec_1<Arg> {}; -template <typename Arg0, typename Arg1>-class promise_handler_selector<void(Arg0, Arg1),-  enable_if_t<is_disposition<Arg0>::value>>-    : public promise_handler_d_1<Arg0, Arg1> {};+template <typename Arg>+class promise_handler_selector<void(std::exception_ptr, Arg)>+  : public promise_handler_ex_1<Arg> {}; -template <typename Arg0, typename... ArgN>-class promise_handler_selector<void(Arg0, ArgN...),-  enable_if_t<!is_disposition<Arg0>::value>>-    : public promise_handler_n<std::tuple<Arg0, ArgN...>> {};+#if defined(ASIO_HAS_VARIADIC_TEMPLATES) -template <typename Arg0, typename... ArgN>-class promise_handler_selector<void(Arg0, ArgN...),-  enable_if_t<is_disposition<Arg0>::value>>-    : public promise_handler_d_n<Arg0, std::tuple<ArgN...>> {};+template <typename... Arg>+class promise_handler_selector<void(Arg...)>+  : public promise_handler_n<std::tuple<Arg...> > {}; +template <typename... Arg>+class promise_handler_selector<void(asio::error_code, Arg...)>+  : public promise_handler_ec_n<std::tuple<Arg...> > {};++template <typename... Arg>+class promise_handler_selector<void(std::exception_ptr, Arg...)>+  : public promise_handler_ex_n<std::tuple<Arg...> > {};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#define ASIO_PRIVATE_PROMISE_SELECTOR_DEF(n) \+  template <typename Arg, ASIO_VARIADIC_TPARAMS(n)> \+  class promise_handler_selector< \+    void(Arg, ASIO_VARIADIC_TARGS(n))> \+      : public promise_handler_n< \+        std::tuple<Arg, ASIO_VARIADIC_TARGS(n)> > {}; \+  \+  template <typename Arg, ASIO_VARIADIC_TPARAMS(n)> \+  class promise_handler_selector< \+    void(asio::error_code, Arg, ASIO_VARIADIC_TARGS(n))> \+      : public promise_handler_ec_n< \+        std::tuple<Arg, ASIO_VARIADIC_TARGS(n)> > {}; \+  \+  template <typename Arg, ASIO_VARIADIC_TPARAMS(n)> \+  class promise_handler_selector< \+    void(std::exception_ptr, Arg, ASIO_VARIADIC_TARGS(n))> \+      : public promise_handler_ex_n< \+        std::tuple<Arg, ASIO_VARIADIC_TARGS(n)> > {}; \+  /**/+  ASIO_VARIADIC_GENERATE_5(ASIO_PRIVATE_PROMISE_SELECTOR_DEF)+#undef ASIO_PRIVATE_PROMISE_SELECTOR_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ // Completion handlers produced from the use_future completion token, when not // using use_future::operator(). template <typename Signature, typename Allocator>@@ -368,7 +637,7 @@     this->create_promise(allocator_);   } -  allocator_type get_allocator() const noexcept+  allocator_type get_allocator() const ASIO_NOEXCEPT   {     return allocator_;   }@@ -381,7 +650,7 @@ struct promise_function_wrapper {   explicit promise_function_wrapper(Function& f)-    : function_(static_cast<Function&&>(f))+    : function_(ASIO_MOVE_CAST(Function)(f))   {   } @@ -398,6 +667,28 @@   Function function_; }; +#if !defined(ASIO_NO_DEPRECATED)++template <typename Function, typename Signature, typename Allocator>+inline void asio_handler_invoke(Function& f,+    promise_handler<Signature, Allocator>* h)+{+  typename promise_handler<Signature, Allocator>::executor_type+    ex(h->get_executor());+  asio::dispatch(ex, promise_function_wrapper<Function>(f));+}++template <typename Function, typename Signature, typename Allocator>+inline void asio_handler_invoke(const Function& f,+    promise_handler<Signature, Allocator>* h)+{+  typename promise_handler<Signature, Allocator>::executor_type+    ex(h->get_executor());+  asio::dispatch(ex, promise_function_wrapper<Function>(f));+}++#endif // !defined(ASIO_NO_DEPRECATED)+ // Helper base class for async_result specialisation. template <typename Signature, typename Allocator> class promise_async_result@@ -413,7 +704,7 @@    return_type get()   {-    return static_cast<return_type&&>(future_);+    return ASIO_MOVE_CAST(return_type)(future_);   }  private:@@ -426,7 +717,7 @@ { public:   packaged_token(Function f, const Allocator& a)-    : function_(static_cast<Function&&>(f)),+    : function_(ASIO_MOVE_CAST(Function)(f)),       allocator_(a)   {   }@@ -447,29 +738,75 @@   typedef void result_type;    packaged_handler(packaged_token<Function, Allocator> t)-    : function_(static_cast<Function&&>(t.function_)),+    : function_(ASIO_MOVE_CAST(Function)(t.function_)),       allocator_(t.allocator_)   {     this->create_promise(allocator_);   } -  allocator_type get_allocator() const noexcept+  allocator_type get_allocator() const ASIO_NOEXCEPT   {     return allocator_;   } +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+   template <typename... Args>-  void operator()(Args&&... args)+  void operator()(ASIO_MOVE_ARG(Args)... args)   {     (promise_invoke_and_set)(*this->p_,-        function_, static_cast<Args&&>(args)...);+        function_, ASIO_MOVE_CAST(Args)(args)...);   } +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++  void operator()()+  {+    (promise_invoke_and_set)(*this->p_, function_);+  }++#define ASIO_PRIVATE_CALL_OP_DEF(n) \+  template <ASIO_VARIADIC_TPARAMS(n)> \+  void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \+  {\+    (promise_invoke_and_set)(*this->p_, \+        function_, ASIO_VARIADIC_MOVE_ARGS(n)); \+  } \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF)+#undef ASIO_PRIVATE_CALL_OP_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ private:   Function function_;   Allocator allocator_; }; +#if !defined(ASIO_NO_DEPRECATED)++template <typename Function,+    typename Function1, typename Allocator, typename Result>+inline void asio_handler_invoke(Function& f,+    packaged_handler<Function1, Allocator, Result>* h)+{+  typename packaged_handler<Function1, Allocator, Result>::executor_type+    ex(h->get_executor());+  asio::dispatch(ex, promise_function_wrapper<Function>(f));+}++template <typename Function,+    typename Function1, typename Allocator, typename Result>+inline void asio_handler_invoke(const Function& f,+    packaged_handler<Function1, Allocator, Result>* h)+{+  typename packaged_handler<Function1, Allocator, Result>::executor_type+    ex(h->get_executor());+  asio::dispatch(ex, promise_function_wrapper<Function>(f));+}++#endif // !defined(ASIO_NO_DEPRECATED)+ // Helper base class for async_result specialisation. template <typename Function, typename Allocator, typename Result> class packaged_async_result@@ -485,7 +822,7 @@    return_type get()   {-    return static_cast<return_type&&>(future_);+    return ASIO_MOVE_CAST(return_type)(future_);   }  private:@@ -495,26 +832,28 @@ } // namespace detail  template <typename Allocator> template <typename Function>-inline detail::packaged_token<decay_t<Function>, Allocator>-use_future_t<Allocator>::operator()(Function&& f) const+inline detail::packaged_token<typename decay<Function>::type, Allocator>+use_future_t<Allocator>::operator()(ASIO_MOVE_ARG(Function) f) const {-  return detail::packaged_token<decay_t<Function>, Allocator>(-      static_cast<Function&&>(f), allocator_);+  return detail::packaged_token<typename decay<Function>::type, Allocator>(+      ASIO_MOVE_CAST(Function)(f), allocator_); }  #if !defined(GENERATING_DOCUMENTATION) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename Allocator, typename Result, typename... Args> class async_result<use_future_t<Allocator>, Result(Args...)>   : public detail::promise_async_result<-      void(decay_t<Args>...), Allocator>+      void(typename decay<Args>::type...), Allocator> { public:   explicit async_result(-    typename detail::promise_async_result<void(decay_t<Args>...),+    typename detail::promise_async_result<void(typename decay<Args>::type...),       Allocator>::completion_handler_type& h)     : detail::promise_async_result<-        void(decay_t<Args>...), Allocator>(h)+        void(typename decay<Args>::type...), Allocator>(h)   {   } };@@ -523,28 +862,100 @@     typename Result, typename... Args> class async_result<detail::packaged_token<Function, Allocator>, Result(Args...)>   : public detail::packaged_async_result<Function, Allocator,-      result_of_t<Function(Args...)>>+      typename result_of<Function(Args...)>::type> { public:   explicit async_result(     typename detail::packaged_async_result<Function, Allocator,-      result_of_t<Function(Args...)>>::completion_handler_type& h)+      typename result_of<Function(Args...)>::type>::completion_handler_type& h)     : detail::packaged_async_result<Function, Allocator,-        result_of_t<Function(Args...)>>(h)+        typename result_of<Function(Args...)>::type>(h)   {   } }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename Allocator, typename Result>+class async_result<use_future_t<Allocator>, Result()>+  : public detail::promise_async_result<void(), Allocator>+{+public:+  explicit async_result(+    typename detail::promise_async_result<+      void(), Allocator>::completion_handler_type& h)+    : detail::promise_async_result<void(), Allocator>(h)+  {+  }+};++template <typename Function, typename Allocator, typename Result>+class async_result<detail::packaged_token<Function, Allocator>, Result()>+  : public detail::packaged_async_result<Function, Allocator,+      typename result_of<Function()>::type>+{+public:+  explicit async_result(+    typename detail::packaged_async_result<Function, Allocator,+      typename result_of<Function()>::type>::completion_handler_type& h)+    : detail::packaged_async_result<Function, Allocator,+        typename result_of<Function()>::type>(h)+  {+  }+};++#define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \+  template <typename Allocator, \+      typename Result, ASIO_VARIADIC_TPARAMS(n)> \+  class async_result<use_future_t<Allocator>, \+      Result(ASIO_VARIADIC_TARGS(n))> \+    : public detail::promise_async_result< \+        void(ASIO_VARIADIC_DECAY(n)), Allocator> \+  { \+  public: \+    explicit async_result( \+      typename detail::promise_async_result< \+        void(ASIO_VARIADIC_DECAY(n)), \+        Allocator>::completion_handler_type& h) \+      : detail::promise_async_result< \+          void(ASIO_VARIADIC_DECAY(n)), Allocator>(h) \+    { \+    } \+  }; \+  \+  template <typename Function, typename Allocator, \+      typename Result, ASIO_VARIADIC_TPARAMS(n)> \+  class async_result<detail::packaged_token<Function, Allocator>, \+      Result(ASIO_VARIADIC_TARGS(n))> \+    : public detail::packaged_async_result<Function, Allocator, \+        typename result_of<Function(ASIO_VARIADIC_TARGS(n))>::type> \+  { \+  public: \+    explicit async_result( \+      typename detail::packaged_async_result<Function, Allocator, \+        typename result_of<Function(ASIO_VARIADIC_TARGS(n))>::type \+        >::completion_handler_type& h) \+      : detail::packaged_async_result<Function, Allocator, \+          typename result_of<Function(ASIO_VARIADIC_TARGS(n))>::type>(h) \+    { \+    } \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF)+#undef ASIO_PRIVATE_ASYNC_RESULT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ namespace traits {  #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)  template <typename T, typename Blocking> struct equality_comparable<-    asio::detail::promise_executor<T, Blocking>>+    asio::detail::promise_executor<T, Blocking> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); };  #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -555,8 +966,8 @@ struct execute_member<     asio::detail::promise_executor<T, Blocking>, Function> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; }; @@ -576,11 +987,11 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef Blocking result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return Blocking();   }@@ -596,8 +1007,8 @@     execution::context_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::system_context& result_type; }; @@ -611,8 +1022,8 @@     execution::blocking_t::possibly_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::detail::promise_executor<T,       execution::blocking_t::possibly_t> result_type; };@@ -623,8 +1034,8 @@     execution::blocking_t::never_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::detail::promise_executor<T,       execution::blocking_t::never_t> result_type; };
link/modules/asio-standalone/asio/include/asio/impl/write.hpp view
@@ -2,7 +2,7 @@ // impl/write.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,7 +23,9 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -60,23 +62,20 @@     typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    >::type) {   return detail::write(s, buffers,       asio::buffer_sequence_begin(buffers),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); }  template <typename SyncWriteStream, typename ConstBufferSequence> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,-    constraint_t<+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    >)+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);@@ -87,9 +86,9 @@ template <typename SyncWriteStream, typename ConstBufferSequence> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,     asio::error_code& ec,-    constraint_t<+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    >)+    >::type) {   return write(s, buffers, transfer_all(), ec); }@@ -98,16 +97,13 @@     typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,     CompletionCondition completion_condition,-    constraint_t<+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = write(s, buffers,-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "write");   return bytes_transferred; }@@ -117,40 +113,37 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1,     typename CompletionCondition> std::size_t write(SyncWriteStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type) {-  decay_t<DynamicBuffer_v1> b(-      static_cast<DynamicBuffer_v1&&>(buffers));+  typename decay<DynamicBuffer_v1>::type b(+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));    std::size_t bytes_transferred = write(s, b.data(),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   b.consume(bytes_transferred);   return bytes_transferred; }  template <typename SyncWriteStream, typename DynamicBuffer_v1> inline std::size_t write(SyncWriteStream& s,-    DynamicBuffer_v1&& buffers,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = write(s,-      static_cast<DynamicBuffer_v1&&>(buffers),+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),       transfer_all(), ec);   asio::detail::throw_error(ec, "write");   return bytes_transferred;@@ -158,38 +151,35 @@  template <typename SyncWriteStream, typename DynamicBuffer_v1> inline std::size_t write(SyncWriteStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >)+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type) {-  return write(s, static_cast<DynamicBuffer_v1&&>(buffers),+  return write(s, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),       transfer_all(), ec); }  template <typename SyncWriteStream, typename DynamicBuffer_v1,     typename CompletionCondition> inline std::size_t write(SyncWriteStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = write(s,-      static_cast<DynamicBuffer_v1&&>(buffers),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "write");   return bytes_transferred; }@@ -201,13 +191,10 @@     typename CompletionCondition> inline std::size_t write(SyncWriteStream& s,     asio::basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition, asio::error_code& ec) {   return write(s, basic_streambuf_ref<Allocator>(b),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); }  template <typename SyncWriteStream, typename Allocator>@@ -229,13 +216,10 @@     typename CompletionCondition> inline std::size_t write(SyncWriteStream& s,     asio::basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition) {   return write(s, basic_streambuf_ref<Allocator>(b),-      static_cast<CompletionCondition&&>(completion_condition));+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition)); }  #endif // !defined(ASIO_NO_IOSTREAM)@@ -246,28 +230,25 @@     typename CompletionCondition> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    >::type) {   std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   buffers.consume(bytes_transferred);   return bytes_transferred; }  template <typename SyncWriteStream, typename DynamicBuffer_v2> inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = write(s,-      static_cast<DynamicBuffer_v2&&>(buffers),+      ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),       transfer_all(), ec);   asio::detail::throw_error(ec, "write");   return bytes_transferred;@@ -276,11 +257,11 @@ template <typename SyncWriteStream, typename DynamicBuffer_v2> inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,     asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >)+    >::type) {-  return write(s, static_cast<DynamicBuffer_v2&&>(buffers),+  return write(s, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),       transfer_all(), ec); } @@ -288,17 +269,14 @@     typename CompletionCondition> inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    >,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    >::type) {   asio::error_code ec;   std::size_t bytes_transferred = write(s,-      static_cast<DynamicBuffer_v2&&>(buffers),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "write");   return bytes_transferred; }@@ -321,10 +299,11 @@         stream_(stream),         buffers_(buffers),         start_(0),-        handler_(static_cast<WriteHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(WriteHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     write_op(const write_op& other)       : base_from_cancellation_state<WriteHandler>(other),         base_from_completion_cond<CompletionCondition>(other),@@ -337,15 +316,18 @@      write_op(write_op&& other)       : base_from_cancellation_state<WriteHandler>(-          static_cast<base_from_cancellation_state<WriteHandler>&&>(other)),+          ASIO_MOVE_CAST(base_from_cancellation_state<+            WriteHandler>)(other)),         base_from_completion_cond<CompletionCondition>(-          static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+          ASIO_MOVE_CAST(base_from_completion_cond<+            CompletionCondition>)(other)),         stream_(other.stream_),-        buffers_(static_cast<buffers_type&&>(other.buffers_)),+        buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)),         start_(other.start_),-        handler_(static_cast<WriteHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(asio::error_code ec,         std::size_t bytes_transferred, int start = 0)@@ -360,7 +342,7 @@           {             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write"));             stream_.async_write_some(buffers_.prepare(max_size),-                static_cast<write_op&&>(*this));+                ASIO_MOVE_CAST(write_op)(*this));           }           return; default:           buffers_.consume(bytes_transferred);@@ -376,7 +358,7 @@           }         } -        static_cast<WriteHandler&&>(handler_)(+        ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(             static_cast<const asio::error_code&>(ec),             static_cast<const std::size_t&>(buffers_.total_consumed()));       }@@ -395,6 +377,38 @@   template <typename AsyncWriteStream, typename ConstBufferSequence,       typename ConstBufferIterator, typename CompletionCondition,       typename WriteHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,+        CompletionCondition, WriteHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncWriteStream, typename ConstBufferSequence,+      typename ConstBufferIterator, typename CompletionCondition,+      typename WriteHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,+        CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncWriteStream, typename ConstBufferSequence,+      typename ConstBufferIterator, typename CompletionCondition,+      typename WriteHandler>   inline bool asio_handler_is_continuation(       write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,         CompletionCondition, WriteHandler>* this_handler)@@ -404,6 +418,36 @@           this_handler->handler_);   } +  template <typename Function, typename AsyncWriteStream,+      typename ConstBufferSequence, typename ConstBufferIterator,+      typename CompletionCondition, typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,+        CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncWriteStream,+      typename ConstBufferSequence, typename ConstBufferIterator,+      typename CompletionCondition, typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      write_op<AsyncWriteStream, ConstBufferSequence, ConstBufferIterator,+        CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncWriteStream, typename ConstBufferSequence,       typename ConstBufferIterator, typename CompletionCondition,       typename WriteHandler>@@ -428,16 +472,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return stream_.get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence,         typename CompletionCondition>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers,-        CompletionCondition&& completion_cond) const+        ASIO_MOVE_ARG(CompletionCondition) completion_cond) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WriteHandler.@@ -467,18 +511,21 @@     DefaultCandidate>   : Associator<WriteHandler, DefaultCandidate> {-  static typename Associator<WriteHandler, DefaultCandidate>::type get(-      const detail::write_op<AsyncWriteStream, ConstBufferSequence,-        ConstBufferIterator, CompletionCondition, WriteHandler>& h) noexcept+  static typename Associator<WriteHandler, DefaultCandidate>::type+  get(const detail::write_op<AsyncWriteStream, ConstBufferSequence,+        ConstBufferIterator, CompletionCondition, WriteHandler>& h)+    ASIO_NOEXCEPT   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::write_op<AsyncWriteStream, ConstBufferSequence,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<WriteHandler, DefaultCandidate>::type)+  get(const detail::write_op<AsyncWriteStream, ConstBufferSequence,         ConstBufferIterator, CompletionCondition, WriteHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -486,6 +533,54 @@  #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncWriteStream,+    typename ConstBufferSequence, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(WriteToken) token,+    typename constraint<+      is_const_buffer_sequence<ConstBufferSequence>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write<AsyncWriteStream> >(),+        token, buffers,+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write<AsyncWriteStream>(s),+      token, buffers,+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncWriteStream, typename ConstBufferSequence,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,+    ASIO_MOVE_ARG(WriteToken) token,+    typename constraint<+      is_const_buffer_sequence<ConstBufferSequence>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write<AsyncWriteStream> >(),+        token, buffers, transfer_all())))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write<AsyncWriteStream>(s),+      token, buffers, transfer_all());+}+ #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)  namespace detail@@ -497,16 +592,17 @@   public:     template <typename BufferSequence>     write_dynbuf_v1_op(AsyncWriteStream& stream,-        BufferSequence&& buffers,+        ASIO_MOVE_ARG(BufferSequence) buffers,         CompletionCondition& completion_condition, WriteHandler& handler)       : stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),         completion_condition_(-          static_cast<CompletionCondition&&>(completion_condition)),-        handler_(static_cast<WriteHandler&&>(handler))+          ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),+        handler_(ASIO_MOVE_CAST(WriteHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     write_dynbuf_v1_op(const write_dynbuf_v1_op& other)       : stream_(other.stream_),         buffers_(other.buffers_),@@ -517,13 +613,14 @@      write_dynbuf_v1_op(write_dynbuf_v1_op&& other)       : stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v1&&>(other.buffers_)),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),         completion_condition_(-          static_cast<CompletionCondition&&>(+          ASIO_MOVE_CAST(CompletionCondition)(             other.completion_condition_)),-        handler_(static_cast<WriteHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(const asio::error_code& ec,         std::size_t bytes_transferred, int start = 0)@@ -532,11 +629,11 @@       {         case 1:         async_write(stream_, buffers_.data(),-            static_cast<CompletionCondition&&>(completion_condition_),-            static_cast<write_dynbuf_v1_op&&>(*this));+            ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),+            ASIO_MOVE_CAST(write_dynbuf_v1_op)(*this));         return; default:         buffers_.consume(bytes_transferred);-        static_cast<WriteHandler&&>(handler_)(ec,+        ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec,             static_cast<const std::size_t&>(bytes_transferred));       }     }@@ -550,6 +647,36 @@    template <typename AsyncWriteStream, typename DynamicBuffer_v1,       typename CompletionCondition, typename WriteHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+        CompletionCondition, WriteHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncWriteStream, typename DynamicBuffer_v1,+      typename CompletionCondition, typename WriteHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+        CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncWriteStream, typename DynamicBuffer_v1,+      typename CompletionCondition, typename WriteHandler>   inline bool asio_handler_is_continuation(       write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,         CompletionCondition, WriteHandler>* this_handler)@@ -558,6 +685,36 @@         this_handler->handler_);   } +  template <typename Function, typename AsyncWriteStream,+      typename DynamicBuffer_v1, typename CompletionCondition,+      typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+        CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncWriteStream,+      typename DynamicBuffer_v1, typename CompletionCondition,+      typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+        CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncWriteStream>   class initiate_async_write_dynbuf_v1   {@@ -569,16 +726,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return stream_.get_executor();     }      template <typename WriteHandler, typename DynamicBuffer_v1,         typename CompletionCondition>-    void operator()(WriteHandler&& handler,-        DynamicBuffer_v1&& buffers,-        CompletionCondition&& completion_cond) const+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+        ASIO_MOVE_ARG(CompletionCondition) completion_cond) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WriteHandler.@@ -587,9 +744,9 @@       non_const_lvalue<WriteHandler> handler2(handler);       non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);       write_dynbuf_v1_op<AsyncWriteStream,-        decay_t<DynamicBuffer_v1>,-          CompletionCondition, decay_t<WriteHandler>>(-            stream_, static_cast<DynamicBuffer_v1&&>(buffers),+        typename decay<DynamicBuffer_v1>::type,+          CompletionCondition, typename decay<WriteHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),               completion_cond2.value, handler2.value)(                 asio::error_code(), 0, 1);     }@@ -611,18 +768,20 @@     DefaultCandidate>   : Associator<WriteHandler, DefaultCandidate> {-  static typename Associator<WriteHandler, DefaultCandidate>::type get(-      const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,-        CompletionCondition, WriteHandler>& h) noexcept+  static typename Associator<WriteHandler, DefaultCandidate>::type+  get(const detail::write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,+        CompletionCondition, WriteHandler>& h) ASIO_NOEXCEPT   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::write_dynbuf_v1_op<AsyncWriteStream,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<WriteHandler, DefaultCandidate>::type)+  get(const detail::write_dynbuf_v1_op<AsyncWriteStream,         DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -630,6 +789,105 @@  #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncWriteStream, typename DynamicBuffer_v1,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    ASIO_MOVE_ARG(WriteToken) token,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        transfer_all())))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+      transfer_all());+}++template <typename AsyncWriteStream,+    typename DynamicBuffer_v1, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(WriteToken) token,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++#if !defined(ASIO_NO_EXTENSIONS)+#if !defined(ASIO_NO_IOSTREAM)++template <typename AsyncWriteStream, typename Allocator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+    asio::basic_streambuf<Allocator>& b,+    ASIO_MOVE_ARG(WriteToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_write(s, basic_streambuf_ref<Allocator>(b),+        ASIO_MOVE_CAST(WriteToken)(token))))+{+  return async_write(s, basic_streambuf_ref<Allocator>(b),+      ASIO_MOVE_CAST(WriteToken)(token));+}++template <typename AsyncWriteStream,+    typename Allocator, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+    asio::basic_streambuf<Allocator>& b,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(WriteToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_write(s, basic_streambuf_ref<Allocator>(b),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+        ASIO_MOVE_CAST(WriteToken)(token))))+{+  return async_write(s, basic_streambuf_ref<Allocator>(b),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+      ASIO_MOVE_CAST(WriteToken)(token));+}++#endif // !defined(ASIO_NO_IOSTREAM)+#endif // !defined(ASIO_NO_EXTENSIONS) #endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)  namespace detail@@ -641,16 +899,17 @@   public:     template <typename BufferSequence>     write_dynbuf_v2_op(AsyncWriteStream& stream,-        BufferSequence&& buffers,+        ASIO_MOVE_ARG(BufferSequence) buffers,         CompletionCondition& completion_condition, WriteHandler& handler)       : stream_(stream),-        buffers_(static_cast<BufferSequence&&>(buffers)),+        buffers_(ASIO_MOVE_CAST(BufferSequence)(buffers)),         completion_condition_(-          static_cast<CompletionCondition&&>(completion_condition)),-        handler_(static_cast<WriteHandler&&>(handler))+          ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),+        handler_(ASIO_MOVE_CAST(WriteHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     write_dynbuf_v2_op(const write_dynbuf_v2_op& other)       : stream_(other.stream_),         buffers_(other.buffers_),@@ -661,13 +920,14 @@      write_dynbuf_v2_op(write_dynbuf_v2_op&& other)       : stream_(other.stream_),-        buffers_(static_cast<DynamicBuffer_v2&&>(other.buffers_)),+        buffers_(ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),         completion_condition_(-          static_cast<CompletionCondition&&>(+          ASIO_MOVE_CAST(CompletionCondition)(             other.completion_condition_)),-        handler_(static_cast<WriteHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(const asio::error_code& ec,         std::size_t bytes_transferred, int start = 0)@@ -676,11 +936,11 @@       {         case 1:         async_write(stream_, buffers_.data(0, buffers_.size()),-            static_cast<CompletionCondition&&>(completion_condition_),-            static_cast<write_dynbuf_v2_op&&>(*this));+            ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),+            ASIO_MOVE_CAST(write_dynbuf_v2_op)(*this));         return; default:         buffers_.consume(bytes_transferred);-        static_cast<WriteHandler&&>(handler_)(ec,+        ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec,             static_cast<const std::size_t&>(bytes_transferred));       }     }@@ -694,6 +954,36 @@    template <typename AsyncWriteStream, typename DynamicBuffer_v2,       typename CompletionCondition, typename WriteHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+        CompletionCondition, WriteHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncWriteStream, typename DynamicBuffer_v2,+      typename CompletionCondition, typename WriteHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+        CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncWriteStream, typename DynamicBuffer_v2,+      typename CompletionCondition, typename WriteHandler>   inline bool asio_handler_is_continuation(       write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,         CompletionCondition, WriteHandler>* this_handler)@@ -702,6 +992,36 @@         this_handler->handler_);   } +  template <typename Function, typename AsyncWriteStream,+      typename DynamicBuffer_v2, typename CompletionCondition,+      typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+        CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncWriteStream,+      typename DynamicBuffer_v2, typename CompletionCondition,+      typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+        CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncWriteStream>   class initiate_async_write_dynbuf_v2   {@@ -713,16 +1033,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return stream_.get_executor();     }      template <typename WriteHandler, typename DynamicBuffer_v2,         typename CompletionCondition>-    void operator()(WriteHandler&& handler,-        DynamicBuffer_v2&& buffers,-        CompletionCondition&& completion_cond) const+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,+        ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,+        ASIO_MOVE_ARG(CompletionCondition) completion_cond) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WriteHandler.@@ -730,11 +1050,12 @@        non_const_lvalue<WriteHandler> handler2(handler);       non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);-      write_dynbuf_v2_op<AsyncWriteStream, decay_t<DynamicBuffer_v2>,-        CompletionCondition, decay_t<WriteHandler>>(-          stream_, static_cast<DynamicBuffer_v2&&>(buffers),-            completion_cond2.value, handler2.value)(-              asio::error_code(), 0, 1);+      write_dynbuf_v2_op<AsyncWriteStream,+        typename decay<DynamicBuffer_v2>::type,+          CompletionCondition, typename decay<WriteHandler>::type>(+            stream_, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+              completion_cond2.value, handler2.value)(+                asio::error_code(), 0, 1);     }    private:@@ -754,24 +1075,76 @@     DefaultCandidate>   : Associator<WriteHandler, DefaultCandidate> {-  static typename Associator<WriteHandler, DefaultCandidate>::type get(-      const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,-        CompletionCondition, WriteHandler>& h) noexcept+  static typename Associator<WriteHandler, DefaultCandidate>::type+  get(const detail::write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,+        CompletionCondition, WriteHandler>& h) ASIO_NOEXCEPT   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::write_dynbuf_v2_op<AsyncWriteStream,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<WriteHandler, DefaultCandidate>::type)+  get(const detail::write_dynbuf_v2_op<AsyncWriteStream,         DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);   } };  #endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncWriteStream, typename DynamicBuffer_v2,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,+    ASIO_MOVE_ARG(WriteToken) token,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        transfer_all())))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+      transfer_all());+}++template <typename AsyncWriteStream,+    typename DynamicBuffer_v2, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(WriteToken) token,+    typename constraint<+      is_dynamic_buffer_v2<DynamicBuffer_v2>::value+    >::type)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),+      token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/impl/write_at.hpp view
@@ -2,7 +2,7 @@ // impl/write_at.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,7 +23,9 @@ #include "asio/detail/bind_handler.hpp" #include "asio/detail/consuming_buffers.hpp" #include "asio/detail/dependent_type.hpp"+#include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp"+#include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/handler_tracking.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -64,14 +66,11 @@     typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d,     uint64_t offset, const ConstBufferSequence& buffers,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition, asio::error_code& ec) {   return detail::write_at_buffer_sequence(d, offset, buffers,       asio::buffer_sequence_begin(buffers),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec); }  template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>@@ -97,14 +96,11 @@     typename CompletionCondition> inline std::size_t write_at(SyncRandomAccessWriteDevice& d,     uint64_t offset, const ConstBufferSequence& buffers,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition) {   asio::error_code ec;   std::size_t bytes_transferred = write_at(d, offset, buffers,-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "write_at");   return bytes_transferred; }@@ -116,13 +112,10 @@     typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d,     uint64_t offset, asio::basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition, asio::error_code& ec) {   std::size_t bytes_transferred = write_at(d, offset, b.data(),-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   b.consume(bytes_transferred);   return bytes_transferred; }@@ -149,14 +142,11 @@     typename CompletionCondition> inline std::size_t write_at(SyncRandomAccessWriteDevice& d,     uint64_t offset, asio::basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    >)+    CompletionCondition completion_condition) {   asio::error_code ec;   std::size_t bytes_transferred = write_at(d, offset, b,-      static_cast<CompletionCondition&&>(completion_condition), ec);+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);   asio::detail::throw_error(ec, "write_at");   return bytes_transferred; }@@ -184,10 +174,11 @@         offset_(offset),         buffers_(buffers),         start_(0),-        handler_(static_cast<WriteHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(WriteHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     write_at_op(const write_at_op& other)       : base_from_cancellation_state<WriteHandler>(other),         base_from_completion_cond<CompletionCondition>(other),@@ -201,16 +192,19 @@      write_at_op(write_at_op&& other)       : base_from_cancellation_state<WriteHandler>(-          static_cast<base_from_cancellation_state<WriteHandler>&&>(other)),+          ASIO_MOVE_CAST(base_from_cancellation_state<+            WriteHandler>)(other)),         base_from_completion_cond<CompletionCondition>(-          static_cast<base_from_completion_cond<CompletionCondition>&&>(other)),+          ASIO_MOVE_CAST(base_from_completion_cond<+            CompletionCondition>)(other)),         device_(other.device_),         offset_(other.offset_),-        buffers_(static_cast<buffers_type&&>(other.buffers_)),+        buffers_(ASIO_MOVE_CAST(buffers_type)(other.buffers_)),         start_(other.start_),-        handler_(static_cast<WriteHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(asio::error_code ec,         std::size_t bytes_transferred, int start = 0)@@ -226,7 +220,7 @@             ASIO_HANDLER_LOCATION((__FILE__, __LINE__, "async_write_at"));             device_.async_write_some_at(                 offset_ + buffers_.total_consumed(), buffers_.prepare(max_size),-                static_cast<write_at_op&&>(*this));+                ASIO_MOVE_CAST(write_at_op)(*this));           }           return; default:           buffers_.consume(bytes_transferred);@@ -242,7 +236,7 @@           }         } -        static_cast<WriteHandler&&>(handler_)(+        ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(             static_cast<const asio::error_code&>(ec),             static_cast<const std::size_t&>(buffers_.total_consumed()));       }@@ -262,6 +256,38 @@   template <typename AsyncRandomAccessWriteDevice,       typename ConstBufferSequence, typename ConstBufferIterator,       typename CompletionCondition, typename WriteHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,+        ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncRandomAccessWriteDevice,+      typename ConstBufferSequence, typename ConstBufferIterator,+      typename CompletionCondition, typename WriteHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,+        ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename AsyncRandomAccessWriteDevice,+      typename ConstBufferSequence, typename ConstBufferIterator,+      typename CompletionCondition, typename WriteHandler>   inline bool asio_handler_is_continuation(       write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,         ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)@@ -271,6 +297,36 @@           this_handler->handler_);   } +  template <typename Function, typename AsyncRandomAccessWriteDevice,+      typename ConstBufferSequence, typename ConstBufferIterator,+      typename CompletionCondition, typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,+        ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename AsyncRandomAccessWriteDevice,+      typename ConstBufferSequence, typename ConstBufferIterator,+      typename CompletionCondition, typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,+        ConstBufferIterator, CompletionCondition, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncRandomAccessWriteDevice,       typename ConstBufferSequence, typename ConstBufferIterator,       typename CompletionCondition, typename WriteHandler>@@ -296,16 +352,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return device_.get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence,         typename CompletionCondition>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         uint64_t offset, const ConstBufferSequence& buffers,-        CompletionCondition&& completion_cond) const+        ASIO_MOVE_ARG(CompletionCondition) completion_cond) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WriteHandler.@@ -335,20 +391,22 @@     DefaultCandidate>   : Associator<WriteHandler, DefaultCandidate> {-  static typename Associator<WriteHandler, DefaultCandidate>::type get(-      const detail::write_at_op<AsyncRandomAccessWriteDevice,+  static typename Associator<WriteHandler, DefaultCandidate>::type+  get(const detail::write_at_op<AsyncRandomAccessWriteDevice,         ConstBufferSequence, ConstBufferIterator,-        CompletionCondition, WriteHandler>& h) noexcept+        CompletionCondition, WriteHandler>& h) ASIO_NOEXCEPT   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::write_at_op<AsyncRandomAccessWriteDevice,+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<WriteHandler, DefaultCandidate>::type)+  get(const detail::write_at_op<AsyncRandomAccessWriteDevice,         ConstBufferSequence, ConstBufferIterator,         CompletionCondition, WriteHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);   }@@ -356,6 +414,52 @@  #endif // !defined(GENERATING_DOCUMENTATION) +template <typename AsyncRandomAccessWriteDevice,+    typename ConstBufferSequence, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,+    uint64_t offset, const ConstBufferSequence& buffers,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(WriteToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write_at<+          AsyncRandomAccessWriteDevice> >(),+        token, offset, buffers,+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),+      token, offset, buffers,+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,+    uint64_t offset, const ConstBufferSequence& buffers,+    ASIO_MOVE_ARG(WriteToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write_at<+          AsyncRandomAccessWriteDevice> >(),+        token, offset, buffers, transfer_all())))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),+      token, offset, buffers, transfer_all());+}+ #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM) @@ -369,10 +473,11 @@         asio::basic_streambuf<Allocator>& streambuf,         WriteHandler& handler)       : streambuf_(streambuf),-        handler_(static_cast<WriteHandler&&>(handler))+        handler_(ASIO_MOVE_CAST(WriteHandler)(handler))     {     } +#if defined(ASIO_HAS_MOVE)     write_at_streambuf_op(const write_at_streambuf_op& other)       : streambuf_(other.streambuf_),         handler_(other.handler_)@@ -381,15 +486,16 @@      write_at_streambuf_op(write_at_streambuf_op&& other)       : streambuf_(other.streambuf_),-        handler_(static_cast<WriteHandler&&>(other.handler_))+        handler_(ASIO_MOVE_CAST(WriteHandler)(other.handler_))     {     }+#endif // defined(ASIO_HAS_MOVE)      void operator()(const asio::error_code& ec,         const std::size_t bytes_transferred)     {       streambuf_.consume(bytes_transferred);-      static_cast<WriteHandler&&>(handler_)(ec, bytes_transferred);+      ASIO_MOVE_OR_LVALUE(WriteHandler)(handler_)(ec, bytes_transferred);     }    //private:@@ -398,6 +504,32 @@   };    template <typename Allocator, typename WriteHandler>+  inline asio_handler_allocate_is_deprecated+  asio_handler_allocate(std::size_t size,+      write_at_streambuf_op<Allocator, WriteHandler>* this_handler)+  {+#if defined(ASIO_NO_DEPRECATED)+    asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+    return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+    return asio_handler_alloc_helpers::allocate(+        size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Allocator, typename WriteHandler>+  inline asio_handler_deallocate_is_deprecated+  asio_handler_deallocate(void* pointer, std::size_t size,+      write_at_streambuf_op<Allocator, WriteHandler>* this_handler)+  {+    asio_handler_alloc_helpers::deallocate(+        pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Allocator, typename WriteHandler>   inline bool asio_handler_is_continuation(       write_at_streambuf_op<Allocator, WriteHandler>* this_handler)   {@@ -405,6 +537,30 @@         this_handler->handler_);   } +  template <typename Function, typename Allocator, typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(Function& function,+      write_at_streambuf_op<Allocator, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }++  template <typename Function, typename Allocator, typename WriteHandler>+  inline asio_handler_invoke_is_deprecated+  asio_handler_invoke(const Function& function,+      write_at_streambuf_op<Allocator, WriteHandler>* this_handler)+  {+    asio_handler_invoke_helpers::invoke(+        function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+    return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+  }+   template <typename AsyncRandomAccessWriteDevice>   class initiate_async_write_at_streambuf   {@@ -417,16 +573,16 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return device_.get_executor();     }      template <typename WriteHandler,         typename Allocator, typename CompletionCondition>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         uint64_t offset, basic_streambuf<Allocator>* b,-        CompletionCondition&& completion_condition) const+        ASIO_MOVE_ARG(CompletionCondition) completion_condition) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WriteHandler.@@ -434,8 +590,8 @@        non_const_lvalue<WriteHandler> handler2(handler);       async_write_at(device_, offset, b->data(),-          static_cast<CompletionCondition&&>(completion_condition),-          write_at_streambuf_op<Allocator, decay_t<WriteHandler>>(+          ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+          write_at_streambuf_op<Allocator, typename decay<WriteHandler>::type>(             *b, handler2.value));     } @@ -453,22 +609,73 @@     DefaultCandidate>   : Associator<WriteHandler, DefaultCandidate> {-  static typename Associator<WriteHandler, DefaultCandidate>::type get(-      const detail::write_at_streambuf_op<Executor, WriteHandler>& h) noexcept+  static typename Associator<WriteHandler, DefaultCandidate>::type+  get(const detail::write_at_streambuf_op<Executor, WriteHandler>& h)+    ASIO_NOEXCEPT   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_);   } -  static auto get(-      const detail::write_at_streambuf_op<Executor, WriteHandler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<WriteHandler, DefaultCandidate>::type)+  get(const detail::write_at_streambuf_op<Executor, WriteHandler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<WriteHandler, DefaultCandidate>::get(h.handler_, c);   } };  #endif // !defined(GENERATING_DOCUMENTATION)++template <typename AsyncRandomAccessWriteDevice,+    typename Allocator, typename CompletionCondition,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,+    uint64_t offset, asio::basic_streambuf<Allocator>& b,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(WriteToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write_at_streambuf<+          AsyncRandomAccessWriteDevice> >(),+        token, offset, &b,+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write_at_streambuf<+        AsyncRandomAccessWriteDevice>(d),+      token, offset, &b,+      ASIO_MOVE_CAST(CompletionCondition)(completion_condition));+}++template <typename AsyncRandomAccessWriteDevice, typename Allocator,+    ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+      std::size_t)) WriteToken>+inline ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,+    uint64_t offset, asio::basic_streambuf<Allocator>& b,+    ASIO_MOVE_ARG(WriteToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_initiate<WriteToken,+      void (asio::error_code, std::size_t)>(+        declval<detail::initiate_async_write_at_streambuf<+          AsyncRandomAccessWriteDevice> >(),+        token, offset, &b, transfer_all())))+{+  return async_initiate<WriteToken,+    void (asio::error_code, std::size_t)>(+      detail::initiate_async_write_at_streambuf<+        AsyncRandomAccessWriteDevice>(d),+      token, offset, &b, transfer_all());+}  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/io_context.hpp view
@@ -2,7 +2,7 @@ // io_context.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,7 +20,6 @@ #include <stdexcept> #include <typeinfo> #include "asio/async_result.hpp"-#include "asio/detail/chrono.hpp" #include "asio/detail/concurrency_hint.hpp" #include "asio/detail/cstdint.hpp" #include "asio/detail/wrapped_handler.hpp"@@ -28,6 +27,10 @@ #include "asio/execution.hpp" #include "asio/execution_context.hpp" +#if defined(ASIO_HAS_CHRONO)+# include "asio/detail/chrono.hpp"+#endif // defined(ASIO_HAS_CHRONO)+ #if defined(ASIO_WINDOWS) || defined(__CYGWIN__) # include "asio/detail/winsock_init.hpp" #elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \@@ -55,10 +58,10 @@    struct io_context_bits   {-    static constexpr uintptr_t blocking_never = 1;-    static constexpr uintptr_t relationship_continuation = 2;-    static constexpr uintptr_t outstanding_work_tracked = 4;-    static constexpr uintptr_t runtime_bits = 3;+    ASIO_STATIC_CONSTEXPR(uintptr_t, blocking_never = 1);+    ASIO_STATIC_CONSTEXPR(uintptr_t, relationship_continuation = 2);+    ASIO_STATIC_CONSTEXPR(uintptr_t, outstanding_work_tracked = 4);+    ASIO_STATIC_CONSTEXPR(uintptr_t, runtime_bits = 3);   }; } // namespace detail @@ -197,6 +200,11 @@   friend class detail::win_iocp_overlapped_ptr; #endif +#if !defined(ASIO_NO_DEPRECATED)+  struct initiate_dispatch;+  struct initiate_post;+#endif // !defined(ASIO_NO_DEPRECATED)+ public:   template <typename Allocator, uintptr_t Bits>   class basic_executor_type;@@ -207,6 +215,11 @@   /// Executor used to submit functions to an io_context.   typedef basic_executor_type<std::allocator<void>, 0> executor_type; +#if !defined(ASIO_NO_DEPRECATED)+  class work;+  friend class work;+#endif // !defined(ASIO_NO_DEPRECATED)+   class service;  #if !defined(ASIO_NO_EXTENSIONS) \@@ -223,15 +236,6 @@    /// Constructor.   /**-   * @param a An allocator that will be used for allocating objects that are-   * associated with the context, such as services and internal state for I/O-   * objects.-   */-  template <typename Allocator>-  io_context(allocator_arg_t, const Allocator& a);--  /// Constructor.-  /**    * Construct with a hint about the required level of concurrency.    *    * @param concurrency_hint A suggestion to the implementation on how many@@ -239,47 +243,6 @@    */   ASIO_DECL explicit io_context(int concurrency_hint); -  /// Constructor.-  /**-   * Construct with a hint about the required level of concurrency.-   *-   * @param a An allocator that will be used for allocating objects that are-   * associated with the context, such as services and internal state for I/O-   * objects.-   *-   * @param concurrency_hint A suggestion to the implementation on how many-   * threads it should allow to run simultaneously.-   */-  template <typename Allocator>-  io_context(allocator_arg_t, const Allocator& a, int concurrency_hint);--  /// Constructor.-  /**-   * Construct with a service maker, to create an initial set of services that-   * will be installed into the execution context at construction time.-   *-   * @param initial_services Used to create the initial services. The @c make-   * function will be called once at the end of execution_context construction.-   */-  ASIO_DECL explicit io_context(-      const execution_context::service_maker& initial_services);--  /// Constructor.-  /**-   * Construct with a service maker, to create an initial set of services that-   * will be installed into the execution context at construction time.-   *-   * @param a An allocator that will be used for allocating objects that are-   * associated with the context, such as services and internal state for I/O-   * objects.-   *-   * @param initial_services Used to create the initial services. The @c make-   * function will be called once at the end of execution_context construction.-   */-  template <typename Allocator>-  io_context(allocator_arg_t, const Allocator& a,-      const service_maker& initial_services);-   /// Destructor.   /**    * On destruction, the io_context performs the following sequence of@@ -315,7 +278,7 @@   ASIO_DECL ~io_context();    /// Obtains the executor associated with the io_context.-  executor_type get_executor() noexcept;+  executor_type get_executor() ASIO_NOEXCEPT;    /// Run the io_context object's event processing loop.   /**@@ -337,13 +300,46 @@    * @note Calling the run() function from a thread that is currently calling    * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on    * the same io_context object may introduce the potential for deadlock. It is-   * the caller's responsibility to avoid this.+   * the caller's reponsibility to avoid this.    *    * The poll() function may also be used to dispatch ready handlers, but    * without blocking.    */   ASIO_DECL count_type run(); +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use non-error_code overload.) Run the io_context object's+  /// event processing loop.+  /**+   * The run() function blocks until all work has finished and there are no+   * more handlers to be dispatched, or until the io_context has been stopped.+   *+   * Multiple threads may call the run() function to set up a pool of threads+   * from which the io_context may execute handlers. All threads that are+   * waiting in the pool are equivalent and the io_context may choose any one+   * of them to invoke a handler.+   *+   * A normal exit from the run() function implies that the io_context object+   * is stopped (the stopped() function returns @c true). Subsequent calls to+   * run(), run_one(), poll() or poll_one() will return immediately unless there+   * is a prior call to restart().+   *+   * @param ec Set to indicate what error occurred, if any.+   *+   * @return The number of handlers that were executed.+   *+   * @note Calling the run() function from a thread that is currently calling+   * one of run(), run_one(), run_for(), run_until(), poll() or poll_one() on+   * the same io_context object may introduce the potential for deadlock. It is+   * the caller's reponsibility to avoid this.+   *+   * The poll() function may also be used to dispatch ready handlers, but+   * without blocking.+   */+  ASIO_DECL count_type run(asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)   /// Run the io_context object's event processing loop for a specified   /// duration.   /**@@ -370,6 +366,7 @@    */   template <typename Clock, typename Duration>   std::size_t run_until(const chrono::time_point<Clock, Duration>& abs_time);+#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)    /// Run the io_context object's event processing loop to execute at most one   /// handler.@@ -386,10 +383,34 @@    * @note Calling the run_one() function from a thread that is currently    * calling one of run(), run_one(), run_for(), run_until(), poll() or    * poll_one() on the same io_context object may introduce the potential for-   * deadlock. It is the caller's responsibility to avoid this.+   * deadlock. It is the caller's reponsibility to avoid this.    */   ASIO_DECL count_type run_one(); +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use non-error_code overload.) Run the io_context object's+  /// event processing loop to execute at most one handler.+  /**+   * The run_one() function blocks until one handler has been dispatched, or+   * until the io_context has been stopped.+   *+   * @return The number of handlers that were executed. A zero return value+   * implies that the io_context object is stopped (the stopped() function+   * returns @c true). Subsequent calls to run(), run_one(), poll() or+   * poll_one() will return immediately unless there is a prior call to+   * restart().+   *+   * @return The number of handlers that were executed.+   *+   * @note Calling the run_one() function from a thread that is currently+   * calling one of run(), run_one(), run_for(), run_until(), poll() or+   * poll_one() on the same io_context object may introduce the potential for+   * deadlock. It is the caller's reponsibility to avoid this.+   */+  ASIO_DECL count_type run_one(asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)   /// Run the io_context object's event processing loop for a specified duration   /// to execute at most one handler.   /**@@ -418,6 +439,7 @@   template <typename Clock, typename Duration>   std::size_t run_one_until(       const chrono::time_point<Clock, Duration>& abs_time);+#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)    /// Run the io_context object's event processing loop to execute ready   /// handlers.@@ -429,6 +451,20 @@    */   ASIO_DECL count_type poll(); +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use non-error_code overload.) Run the io_context object's+  /// event processing loop to execute ready handlers.+  /**+   * The poll() function runs handlers that are ready to run, without blocking,+   * until the io_context has been stopped or there are no more ready handlers.+   *+   * @param ec Set to indicate what error occurred, if any.+   *+   * @return The number of handlers that were executed.+   */+  ASIO_DECL count_type poll(asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Run the io_context object's event processing loop to execute one ready   /// handler.   /**@@ -439,6 +475,20 @@    */   ASIO_DECL count_type poll_one(); +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use non-error_code overload.) Run the io_context object's+  /// event processing loop to execute one ready handler.+  /**+   * The poll_one() function runs at most one handler that is ready to run,+   * without blocking.+   *+   * @param ec Set to indicate what error occurred, if any.+   *+   * @return The number of handlers that were executed.+   */+  ASIO_DECL count_type poll_one(asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Stop the io_context object's event processing loop.   /**    * This function does not block, but instead simply signals the io_context to@@ -474,6 +524,79 @@   ASIO_DECL void restart();  #if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use restart().) Reset the io_context in preparation for a+  /// subsequent run() invocation.+  /**+   * This function must be called prior to any second or later set of+   * invocations of the run(), run_one(), poll() or poll_one() functions when a+   * previous invocation of these functions returned due to the io_context+   * being stopped or running out of work. After a call to restart(), the+   * io_context object's stopped() function will return @c false.+   *+   * This function must not be called while there are any unfinished calls to+   * the run(), run_one(), poll() or poll_one() functions.+   */+  void reset();++  /// (Deprecated: Use asio::dispatch().) Request the io_context to+  /// invoke the given handler.+  /**+   * This function is used to ask the io_context to execute the given handler.+   *+   * The io_context guarantees that the handler will only be called in a thread+   * in which the run(), run_one(), poll() or poll_one() member functions is+   * currently being invoked. The handler may be executed inside this function+   * if the guarantee can be met.+   *+   * @param handler The handler to be called. The io_context will make+   * a copy of the handler object as required. The function signature of the+   * handler must be: @code void handler(); @endcode+   *+   * @note This function throws an exception only if:+   *+   * @li the handler's @c asio_handler_allocate function; or+   *+   * @li the handler's copy constructor+   *+   * throws an exception.+   */+  template <typename LegacyCompletionHandler>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+  dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+      async_initiate<LegacyCompletionHandler, void ()>(+          declval<initiate_dispatch>(), handler, this)));++  /// (Deprecated: Use asio::post().) Request the io_context to invoke+  /// the given handler and return immediately.+  /**+   * This function is used to ask the io_context to execute the given handler,+   * but without allowing the io_context to call the handler from inside this+   * function.+   *+   * The io_context guarantees that the handler will only be called in a thread+   * in which the run(), run_one(), poll() or poll_one() member functions is+   * currently being invoked.+   *+   * @param handler The handler to be called. The io_context will make+   * a copy of the handler object as required. The function signature of the+   * handler must be: @code void handler(); @endcode+   *+   * @note This function throws an exception only if:+   *+   * @li the handler's @c asio_handler_allocate function; or+   *+   * @li the handler's copy constructor+   *+   * throws an exception.+   */+  template <typename LegacyCompletionHandler>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+  post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+      async_initiate<LegacyCompletionHandler, void ()>(+          declval<initiate_post>(), handler, this)));+   /// (Deprecated: Use asio::bind_executor().) Create a new handler that   /// automatically dispatches the wrapped handler on the io_context.   /**@@ -494,8 +617,7 @@    * then the return value is a function object with the signature    * @code void g(A1 a1, ... An an); @endcode    * that, when invoked, executes code equivalent to:-   * @code asio::dispatch(io_context,-   *     boost::bind(f, a1, ... an)); @endcode+   * @code io_context.dispatch(boost::bind(f, a1, ... an)); @endcode    */   template <typename Handler> #if defined(GENERATING_DOCUMENTATION)@@ -507,9 +629,12 @@ #endif // !defined(ASIO_NO_DEPRECATED)  private:-  io_context(const io_context&) = delete;-  io_context& operator=(const io_context&) = delete;+  io_context(const io_context&) ASIO_DELETED;+  io_context& operator=(const io_context&) ASIO_DELETED; +  // Helper function to add the implementation.+  ASIO_DECL impl_type& add_impl(impl_type* impl);+   // Backwards compatible overload for use with services derived from   // io_context::service.   template <typename Service>@@ -526,6 +651,10 @@   impl_type& impl_; }; +namespace detail {++} // namespace detail+ /// Executor implementation type used to submit functions to an io_context. template <typename Allocator, uintptr_t Bits> class io_context::basic_executor_type :@@ -533,7 +662,8 @@ { public:   /// Copy constructor.-  basic_executor_type(const basic_executor_type& other) noexcept+  basic_executor_type(+      const basic_executor_type& other) ASIO_NOEXCEPT     : Allocator(static_cast<const Allocator&>(other)),       target_(other.target_)   {@@ -542,17 +672,19 @@         context_ptr()->impl_.work_started();   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.-  basic_executor_type(basic_executor_type&& other) noexcept-    : Allocator(static_cast<Allocator&&>(other)),+  basic_executor_type(basic_executor_type&& other) ASIO_NOEXCEPT+    : Allocator(ASIO_MOVE_CAST(Allocator)(other)),       target_(other.target_)   {     if (Bits & outstanding_work_tracked)       other.target_ = 0;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destructor.-  ~basic_executor_type() noexcept+  ~basic_executor_type() ASIO_NOEXCEPT   {     if (Bits & outstanding_work_tracked)       if (context_ptr())@@ -560,10 +692,14 @@   }    /// Assignment operator.-  basic_executor_type& operator=(const basic_executor_type& other) noexcept;+  basic_executor_type& operator=(+      const basic_executor_type& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move assignment operator.-  basic_executor_type& operator=(basic_executor_type&& other) noexcept;+  basic_executor_type& operator=(+      basic_executor_type&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  #if !defined(GENERATING_DOCUMENTATION) private:@@ -581,7 +717,8 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::blocking.possibly); @endcode    */-  constexpr basic_executor_type require(execution::blocking_t::possibly_t) const+  ASIO_CONSTEXPR basic_executor_type require(+      execution::blocking_t::possibly_t) const   {     return basic_executor_type(context_ptr(),         *this, bits() & ~blocking_never);@@ -597,7 +734,8 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::blocking.never); @endcode    */-  constexpr basic_executor_type require(execution::blocking_t::never_t) const+  ASIO_CONSTEXPR basic_executor_type require(+      execution::blocking_t::never_t) const   {     return basic_executor_type(context_ptr(),         *this, bits() | blocking_never);@@ -613,7 +751,8 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::relationship.fork); @endcode    */-  constexpr basic_executor_type require(execution::relationship_t::fork_t) const+  ASIO_CONSTEXPR basic_executor_type require(+      execution::relationship_t::fork_t) const   {     return basic_executor_type(context_ptr(),         *this, bits() & ~relationship_continuation);@@ -629,7 +768,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::relationship.continuation); @endcode    */-  constexpr basic_executor_type require(+  ASIO_CONSTEXPR basic_executor_type require(       execution::relationship_t::continuation_t) const   {     return basic_executor_type(context_ptr(),@@ -646,7 +785,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::outstanding_work.tracked); @endcode    */-  constexpr basic_executor_type<Allocator,+  ASIO_CONSTEXPR basic_executor_type<Allocator,       ASIO_UNSPECIFIED(Bits | outstanding_work_tracked)>   require(execution::outstanding_work_t::tracked_t) const   {@@ -664,7 +803,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::outstanding_work.untracked); @endcode    */-  constexpr basic_executor_type<Allocator,+  ASIO_CONSTEXPR basic_executor_type<Allocator,       ASIO_UNSPECIFIED(Bits & ~outstanding_work_tracked)>   require(execution::outstanding_work_t::untracked_t) const   {@@ -683,7 +822,7 @@    *     asio::execution::allocator(my_allocator)); @endcode    */   template <typename OtherAllocator>-  constexpr basic_executor_type<OtherAllocator, Bits>+  ASIO_CONSTEXPR basic_executor_type<OtherAllocator, Bits>   require(execution::allocator_t<OtherAllocator> a) const   {     return basic_executor_type<OtherAllocator, Bits>(@@ -700,7 +839,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::allocator); @endcode    */-  constexpr basic_executor_type<std::allocator<void>, Bits>+  ASIO_CONSTEXPR basic_executor_type<std::allocator<void>, Bits>   require(execution::allocator_t<void>) const   {     return basic_executor_type<std::allocator<void>, Bits>(@@ -725,7 +864,8 @@    *       == asio::execution::mapping.thread)    *   ... @endcode    */-  static constexpr execution::mapping_t query(execution::mapping_t) noexcept+  static ASIO_CONSTEXPR execution::mapping_t query(+      execution::mapping_t) ASIO_NOEXCEPT   {     return execution::mapping.thread;   }@@ -740,7 +880,7 @@    * asio::io_context& ctx = asio::query(    *     ex, asio::execution::context); @endcode    */-  io_context& query(execution::context_t) const noexcept+  io_context& query(execution::context_t) const ASIO_NOEXCEPT   {     return *context_ptr();   }@@ -756,7 +896,8 @@    *       == asio::execution::blocking.always)    *   ... @endcode    */-  constexpr execution::blocking_t query(execution::blocking_t) const noexcept+  ASIO_CONSTEXPR execution::blocking_t query(+      execution::blocking_t) const ASIO_NOEXCEPT   {     return (bits() & blocking_never)       ? execution::blocking_t(execution::blocking.never)@@ -774,8 +915,8 @@    *       == asio::execution::relationship.continuation)    *   ... @endcode    */-  constexpr execution::relationship_t query(-      execution::relationship_t) const noexcept+  ASIO_CONSTEXPR execution::relationship_t query(+      execution::relationship_t) const ASIO_NOEXCEPT   {     return (bits() & relationship_continuation)       ? execution::relationship_t(execution::relationship.continuation)@@ -793,8 +934,8 @@    *       == asio::execution::outstanding_work.tracked)    *   ... @endcode    */-  static constexpr execution::outstanding_work_t query(-      execution::outstanding_work_t) noexcept+  static ASIO_CONSTEXPR execution::outstanding_work_t query(+      execution::outstanding_work_t) ASIO_NOEXCEPT   {     return (Bits & outstanding_work_tracked)       ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -812,8 +953,8 @@    *     asio::execution::allocator); @endcode    */   template <typename OtherAllocator>-  constexpr Allocator query(-      execution::allocator_t<OtherAllocator>) const noexcept+  ASIO_CONSTEXPR Allocator query(+      execution::allocator_t<OtherAllocator>) const ASIO_NOEXCEPT   {     return static_cast<const Allocator&>(*this);   }@@ -828,7 +969,8 @@    * auto alloc = asio::query(ex,    *     asio::execution::allocator); @endcode    */-  constexpr Allocator query(execution::allocator_t<void>) const noexcept+  ASIO_CONSTEXPR Allocator query(+      execution::allocator_t<void>) const ASIO_NOEXCEPT   {     return static_cast<const Allocator&>(*this);   }@@ -839,14 +981,14 @@    * @return @c true if the current thread is running the io_context. Otherwise    * returns @c false.    */-  bool running_in_this_thread() const noexcept;+  bool running_in_this_thread() const ASIO_NOEXCEPT;    /// Compare two executors for equality.   /**    * Two executors are equal if they refer to the same underlying io_context.    */   friend bool operator==(const basic_executor_type& a,-      const basic_executor_type& b) noexcept+      const basic_executor_type& b) ASIO_NOEXCEPT   {     return a.target_ == b.target_       && static_cast<const Allocator&>(a) == static_cast<const Allocator&>(b);@@ -857,7 +999,7 @@    * Two executors are equal if they refer to the same underlying io_context.    */   friend bool operator!=(const basic_executor_type& a,-      const basic_executor_type& b) noexcept+      const basic_executor_type& b) ASIO_NOEXCEPT   {     return a.target_ != b.target_       || static_cast<const Allocator&>(a) != static_cast<const Allocator&>(b);@@ -865,12 +1007,12 @@    /// Execution function.   template <typename Function>-  void execute(Function&& f) const;+  void execute(ASIO_MOVE_ARG(Function) f) const;  #if !defined(ASIO_NO_TS_EXECUTORS) public:   /// Obtain the underlying execution context.-  io_context& context() const noexcept;+  io_context& context() const ASIO_NOEXCEPT;    /// Inform the io_context that it has some outstanding work to do.   /**@@ -878,7 +1020,7 @@    * This ensures that the io_context's run() and run_one() functions do not    * exit while the work is underway.    */-  void on_work_started() const noexcept;+  void on_work_started() const ASIO_NOEXCEPT;    /// Inform the io_context that some work is no longer outstanding.   /**@@ -886,7 +1028,7 @@    * finished. Once the count of unfinished work reaches zero, the io_context    * is stopped and the run() and run_one() functions may exit.    */-  void on_work_finished() const noexcept;+  void on_work_finished() const ASIO_NOEXCEPT;    /// Request the io_context to invoke the given function object.   /**@@ -903,7 +1045,8 @@    * internal storage needed for function invocation.    */   template <typename Function, typename OtherAllocator>-  void dispatch(Function&& f, const OtherAllocator& a) const;+  void dispatch(ASIO_MOVE_ARG(Function) f,+      const OtherAllocator& a) const;    /// Request the io_context to invoke the given function object.   /**@@ -919,7 +1062,8 @@    * internal storage needed for function invocation.    */   template <typename Function, typename OtherAllocator>-  void post(Function&& f, const OtherAllocator& a) const;+  void post(ASIO_MOVE_ARG(Function) f,+      const OtherAllocator& a) const;    /// Request the io_context to invoke the given function object.   /**@@ -939,7 +1083,8 @@    * internal storage needed for function invocation.    */   template <typename Function, typename OtherAllocator>-  void defer(Function&& f, const OtherAllocator& a) const;+  void defer(ASIO_MOVE_ARG(Function) f,+      const OtherAllocator& a) const; #endif // !defined(ASIO_NO_TS_EXECUTORS)  private:@@ -947,7 +1092,7 @@   template <typename, uintptr_t> friend class basic_executor_type;    // Constructor used by io_context::get_executor().-  explicit basic_executor_type(io_context& i) noexcept+  explicit basic_executor_type(io_context& i) ASIO_NOEXCEPT     : Allocator(),       target_(reinterpret_cast<uintptr_t>(&i))   {@@ -957,7 +1102,7 @@    // Constructor used by require().   basic_executor_type(io_context* i,-      const Allocator& a, uintptr_t bits) noexcept+      const Allocator& a, uintptr_t bits) ASIO_NOEXCEPT     : Allocator(a),       target_(reinterpret_cast<uintptr_t>(i) | bits)   {@@ -966,12 +1111,12 @@         context_ptr()->impl_.work_started();   } -  io_context* context_ptr() const noexcept+  io_context* context_ptr() const ASIO_NOEXCEPT   {     return reinterpret_cast<io_context*>(target_ & ~runtime_bits);   } -  uintptr_t bits() const noexcept+  uintptr_t bits() const ASIO_NOEXCEPT   {     return target_ & runtime_bits;   }@@ -980,6 +1125,57 @@   uintptr_t target_; }; +#if !defined(ASIO_NO_DEPRECATED)+/// (Deprecated: Use executor_work_guard.) Class to inform the io_context when+/// it has work to do.+/**+ * The work class is used to inform the io_context when work starts and+ * finishes. This ensures that the io_context object's run() function will not+ * exit while work is underway, and that it does exit when there is no+ * unfinished work remaining.+ *+ * The work class is copy-constructible so that it may be used as a data member+ * in a handler class. It is not assignable.+ */+class io_context::work+{+public:+  /// Constructor notifies the io_context that work is starting.+  /**+   * The constructor is used to inform the io_context that some work has begun.+   * This ensures that the io_context object's run() function will not exit+   * while the work is underway.+   */+  explicit work(asio::io_context& io_context);++  /// Copy constructor notifies the io_context that work is starting.+  /**+   * The constructor is used to inform the io_context that some work has begun.+   * This ensures that the io_context object's run() function will not exit+   * while the work is underway.+   */+  work(const work& other);++  /// Destructor notifies the io_context that the work is complete.+  /**+   * The destructor is used to inform the io_context that some work has+   * finished. Once the count of unfinished work reaches zero, the io_context+   * object's run() function is permitted to exit.+   */+  ~work();++  /// Get the io_context associated with the work.+  asio::io_context& get_io_context();++private:+  // Prevent assignment.+  void operator=(const work& other);++  // The io_context implementation.+  detail::io_context_impl& io_context_impl_;+};+#endif // !defined(ASIO_NO_DEPRECATED)+ /// Base class for all io_context services. class io_context::service   : public execution_context::service@@ -992,6 +1188,12 @@   /// Destroy all user-defined handler objects owned by the service.   ASIO_DECL virtual void shutdown(); +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use shutdown().) Destroy all user-defined handler objects+  /// owned by the service.+  ASIO_DECL virtual void shutdown_service();+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Handle notification of a fork-related event to perform any necessary   /// housekeeping.   /**@@ -1001,6 +1203,17 @@   ASIO_DECL virtual void notify_fork(       execution_context::fork_event event); +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use notify_fork().) Handle notification of a fork-related+  /// event to perform any necessary housekeeping.+  /**+   * This function is not a pure virtual so that services only have to+   * implement it if necessary. The default implementation does nothing.+   */+  ASIO_DECL virtual void fork_service(+      execution_context::fork_event event);+#endif // !defined(ASIO_NO_DEPRECATED)+ protected:   /// Constructor.   /**@@ -1045,8 +1258,8 @@     asio::io_context::basic_executor_type<Allocator, Bits>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); };  #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -1059,8 +1272,8 @@     Function   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; }; @@ -1074,8 +1287,8 @@     asio::execution::blocking_t::possibly_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::io_context::basic_executor_type<       Allocator, Bits> result_type; };@@ -1086,8 +1299,8 @@     asio::execution::blocking_t::never_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::io_context::basic_executor_type<       Allocator, Bits> result_type; };@@ -1098,8 +1311,8 @@     asio::execution::relationship_t::fork_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::io_context::basic_executor_type<       Allocator, Bits> result_type; };@@ -1110,8 +1323,8 @@     asio::execution::relationship_t::continuation_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::io_context::basic_executor_type<       Allocator, Bits> result_type; };@@ -1122,8 +1335,8 @@     asio::execution::outstanding_work_t::tracked_t   > : asio::detail::io_context_bits {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::io_context::basic_executor_type<       Allocator, Bits | outstanding_work_tracked> result_type; };@@ -1134,8 +1347,8 @@     asio::execution::outstanding_work_t::untracked_t   > : asio::detail::io_context_bits {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::io_context::basic_executor_type<       Allocator, Bits & ~outstanding_work_tracked> result_type; };@@ -1146,8 +1359,8 @@     asio::execution::allocator_t<void>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::io_context::basic_executor_type<       std::allocator<void>, Bits> result_type; };@@ -1159,8 +1372,8 @@     asio::execution::allocator_t<OtherAllocator>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::io_context::basic_executor_type<       OtherAllocator, Bits> result_type; };@@ -1181,11 +1394,11 @@     >::type   > : asio::detail::io_context_bits {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::outstanding_work_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return (Bits & outstanding_work_tracked)       ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -1205,11 +1418,11 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::mapping_t::thread_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -1231,8 +1444,8 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::blocking_t result_type; }; @@ -1248,8 +1461,8 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::relationship_t result_type; }; @@ -1259,8 +1472,8 @@     asio::execution::context_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::io_context& result_type; }; @@ -1270,8 +1483,8 @@     asio::execution::allocator_t<void>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef Allocator result_type; }; @@ -1281,8 +1494,8 @@     asio::execution::allocator_t<OtherAllocator>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef Allocator result_type; }; 
link/modules/asio-standalone/asio/include/asio/io_context_strand.hpp view
@@ -2,7 +2,7 @@ // io_context_strand.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -54,18 +54,19 @@  * if any of the following conditions are true:  *  * @li @c s.post(a) happens-before @c s.post(b)- *+ *   * @li @c s.post(a) happens-before @c s.dispatch(b), where the latter is  * performed outside the strand- *+ *   * @li @c s.dispatch(a) happens-before @c s.post(b), where the former is  * performed outside the strand- *+ *   * @li @c s.dispatch(a) happens-before @c s.dispatch(b), where both are  * performed outside the strand- *- * then @c a() happens-before @c b()- *+ *   + * then @c asio_handler_invoke(a1, &a1) happens-before+ * @c asio_handler_invoke(b1, &b1).+ *   * Note that in the following case:  * @code async_op_1(..., s.wrap(a));  * async_op_2(..., s.wrap(b)); @endcode@@ -87,6 +88,12 @@  */ class io_context::strand {+private:+#if !defined(ASIO_NO_DEPRECATED)+  struct initiate_dispatch;+  struct initiate_post;+#endif // !defined(ASIO_NO_DEPRECATED)+ public:   /// Constructor.   /**@@ -102,17 +109,6 @@     service_.construct(impl_);   } -  /// Copy constructor.-  /**-   * Creates a copy such that both strand objects share the same underlying-   * state.-   */-  strand(const strand& other) noexcept-    : service_(other.service_),-      impl_(other.impl_)-  {-  }-   /// Destructor.   /**    * Destroys a strand.@@ -125,7 +121,7 @@   }    /// Obtain the underlying execution context.-  asio::io_context& context() const noexcept+  asio::io_context& context() const ASIO_NOEXCEPT   {     return service_.get_io_context();   }@@ -134,7 +130,7 @@   /**    * The strand delegates this call to its underlying io_context.    */-  void on_work_started() const noexcept+  void on_work_started() const ASIO_NOEXCEPT   {     context().get_executor().on_work_started();   }@@ -143,7 +139,7 @@   /**    * The strand delegates this call to its underlying io_context.    */-  void on_work_finished() const noexcept+  void on_work_finished() const ASIO_NOEXCEPT   {     context().get_executor().on_work_finished();   }@@ -164,13 +160,46 @@    * internal storage needed for function invocation.    */   template <typename Function, typename Allocator>-  void dispatch(Function&& f, const Allocator& a) const+  void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const   {-    decay_t<Function> tmp(static_cast<Function&&>(f));+    typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));     service_.dispatch(impl_, tmp);     (void)a;   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use asio::dispatch().) Request the strand to invoke+  /// the given handler.+  /**+   * This function is used to ask the strand to execute the given handler.+   *+   * The strand object guarantees that handlers posted or dispatched through+   * the strand will not be executed concurrently. The handler may be executed+   * inside this function if the guarantee can be met. If this function is+   * called from within a handler that was posted or dispatched through the same+   * strand, then the new handler will be executed immediately.+   *+   * The strand's guarantee is in addition to the guarantee provided by the+   * underlying io_context. The io_context guarantees that the handler will only+   * be called in a thread in which the io_context's run member function is+   * currently being invoked.+   *+   * @param handler The handler to be called. The strand will make a copy of the+   * handler object as required. The function signature of the handler must be:+   * @code void handler(); @endcode+   */+  template <typename LegacyCompletionHandler>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+  dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+      async_initiate<LegacyCompletionHandler, void ()>(+          declval<initiate_dispatch>(), handler, this)))+  {+    return async_initiate<LegacyCompletionHandler, void ()>(+        initiate_dispatch(), handler, this);+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Request the strand to invoke the given function object.   /**    * This function is used to ask the executor to execute the given function@@ -185,13 +214,42 @@    * internal storage needed for function invocation.    */   template <typename Function, typename Allocator>-  void post(Function&& f, const Allocator& a) const+  void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const   {-    decay_t<Function> tmp(static_cast<Function&&>(f));+    typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));     service_.post(impl_, tmp);     (void)a;   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use asio::post().) Request the strand to invoke the+  /// given handler and return immediately.+  /**+   * This function is used to ask the strand to execute the given handler, but+   * without allowing the strand to call the handler from inside this function.+   *+   * The strand object guarantees that handlers posted or dispatched through+   * the strand will not be executed concurrently. The strand's guarantee is in+   * addition to the guarantee provided by the underlying io_context. The+   * io_context guarantees that the handler will only be called in a thread in+   * which the io_context's run member function is currently being invoked.+   *+   * @param handler The handler to be called. The strand will make a copy of the+   * handler object as required. The function signature of the handler must be:+   * @code void handler(); @endcode+   */+  template <typename LegacyCompletionHandler>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(LegacyCompletionHandler, void ())+  post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+      async_initiate<LegacyCompletionHandler, void ()>(+          declval<initiate_post>(), handler, this)))+  {+    return async_initiate<LegacyCompletionHandler, void ()>(+        initiate_post(), handler, this);+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Request the strand to invoke the given function object.   /**    * This function is used to ask the executor to execute the given function@@ -206,9 +264,9 @@    * internal storage needed for function invocation.    */   template <typename Function, typename Allocator>-  void defer(Function&& f, const Allocator& a) const+  void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const   {-    decay_t<Function> tmp(static_cast<Function&&>(f));+    typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));     service_.post(impl_, tmp);     (void)a;   }@@ -233,7 +291,7 @@    * then the return value is a function object with the signature    * @code void g(A1 a1, ... An an); @endcode    * that, when invoked, executes code equivalent to:-   * @code asio::dispatch(strand, boost::bind(f, a1, ... an)); @endcode+   * @code strand.dispatch(boost::bind(f, a1, ... an)); @endcode    */   template <typename Handler> #if defined(GENERATING_DOCUMENTATION)@@ -254,7 +312,7 @@    * submitted to the strand using post(), dispatch() or wrap(). Otherwise    * returns @c false.    */-  bool running_in_this_thread() const noexcept+  bool running_in_this_thread() const ASIO_NOEXCEPT   {     return service_.running_in_this_thread(impl_);   }@@ -264,7 +322,7 @@    * Two strands are equal if they refer to the same ordered, non-concurrent    * state.    */-  friend bool operator==(const strand& a, const strand& b) noexcept+  friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT   {     return a.impl_ == b.impl_;   }@@ -274,12 +332,48 @@    * Two strands are equal if they refer to the same ordered, non-concurrent    * state.    */-  friend bool operator!=(const strand& a, const strand& b) noexcept+  friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT   {     return a.impl_ != b.impl_;   }  private:+#if !defined(ASIO_NO_DEPRECATED)+  struct initiate_dispatch+  {+    template <typename LegacyCompletionHandler>+    void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,+        strand* self) const+    {+      // If you get an error on the following line it means that your+      // handler does not meet the documented type requirements for a+      // LegacyCompletionHandler.+      ASIO_LEGACY_COMPLETION_HANDLER_CHECK(+          LegacyCompletionHandler, handler) type_check;++      detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);+      self->service_.dispatch(self->impl_, handler2.value);+    }+  };++  struct initiate_post+  {+    template <typename LegacyCompletionHandler>+    void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,+        strand* self) const+    {+      // If you get an error on the following line it means that your+      // handler does not meet the documented type requirements for a+      // LegacyCompletionHandler.+      ASIO_LEGACY_COMPLETION_HANDLER_CHECK(+          LegacyCompletionHandler, handler) type_check;++      detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);+      self->service_.post(self->impl_, handler2.value);+    }+  };+#endif // !defined(ASIO_NO_DEPRECATED)+   asio::detail::strand_service& service_;   mutable asio::detail::strand_service::implementation_type impl_; };
+ link/modules/asio-standalone/asio/include/asio/io_service.hpp view
@@ -0,0 +1,33 @@+//+// io_service.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_IO_SERVICE_HPP+#define ASIO_IO_SERVICE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/io_context.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {++#if !defined(ASIO_NO_DEPRECATED)+/// Typedef for backwards compatibility.+typedef io_context io_service;+#endif // !defined(ASIO_NO_DEPRECATED)++} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_IO_SERVICE_HPP
+ link/modules/asio-standalone/asio/include/asio/io_service_strand.hpp view
@@ -0,0 +1,20 @@+//+// io_service_strand.hpp+// ~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_IO_SERVICE_STRAND_HPP+#define ASIO_IO_SERVICE_STRAND_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/io_context_strand.hpp"++#endif // ASIO_IO_SERVICE_STRAND_HPP
link/modules/asio-standalone/asio/include/asio/ip/address.hpp view
@@ -2,7 +2,7 @@ // ip/address.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,7 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <functional> #include <string> #include "asio/detail/throw_exception.hpp" #include "asio/detail/string_view.hpp"@@ -26,6 +25,10 @@ #include "asio/ip/address_v6.hpp" #include "asio/ip/bad_address_cast.hpp" +#if defined(ASIO_HAS_STD_HASH)+# include <functional>+#endif // defined(ASIO_HAS_STD_HASH)+ #if !defined(ASIO_NO_IOSTREAM) # include <iosfwd> #endif // !defined(ASIO_NO_IOSTREAM)@@ -48,44 +51,48 @@ { public:   /// Default constructor.-  ASIO_DECL address() noexcept;+  ASIO_DECL address() ASIO_NOEXCEPT;    /// Construct an address from an IPv4 address.   ASIO_DECL address(-      const asio::ip::address_v4& ipv4_address) noexcept;+      const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT;    /// Construct an address from an IPv6 address.   ASIO_DECL address(-      const asio::ip::address_v6& ipv6_address) noexcept;+      const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT;    /// Copy constructor.-  ASIO_DECL address(const address& other) noexcept;+  ASIO_DECL address(const address& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  ASIO_DECL address(address&& other) noexcept;+  ASIO_DECL address(address&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE)    /// Assign from another address.-  ASIO_DECL address& operator=(const address& other) noexcept;+  ASIO_DECL address& operator=(const address& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE)   /// Move-assign from another address.-  ASIO_DECL address& operator=(address&& other) noexcept;+  ASIO_DECL address& operator=(address&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE)    /// Assign from an IPv4 address.   ASIO_DECL address& operator=(-      const asio::ip::address_v4& ipv4_address) noexcept;+      const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT;    /// Assign from an IPv6 address.   ASIO_DECL address& operator=(-      const asio::ip::address_v6& ipv6_address) noexcept;+      const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT;    /// Get whether the address is an IP version 4 address.-  bool is_v4() const noexcept+  bool is_v4() const ASIO_NOEXCEPT   {     return type_ == ipv4;   }    /// Get whether the address is an IP version 6 address.-  bool is_v6() const noexcept+  bool is_v6() const ASIO_NOEXCEPT   {     return type_ == ipv6;   }@@ -99,47 +106,73 @@   /// Get the address as a string.   ASIO_DECL std::string to_string() const; +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use other overload.) Get the address as a string.+  ASIO_DECL std::string to_string(asio::error_code& ec) const;++  /// (Deprecated: Use make_address().) Create an address from an IPv4 address+  /// string in dotted decimal form, or from an IPv6 address in hexadecimal+  /// notation.+  static address from_string(const char* str);++  /// (Deprecated: Use make_address().) Create an address from an IPv4 address+  /// string in dotted decimal form, or from an IPv6 address in hexadecimal+  /// notation.+  static address from_string(const char* str, asio::error_code& ec);++  /// (Deprecated: Use make_address().) Create an address from an IPv4 address+  /// string in dotted decimal form, or from an IPv6 address in hexadecimal+  /// notation.+  static address from_string(const std::string& str);++  /// (Deprecated: Use make_address().) Create an address from an IPv4 address+  /// string in dotted decimal form, or from an IPv6 address in hexadecimal+  /// notation.+  static address from_string(+      const std::string& str, asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Determine whether the address is a loopback address.-  ASIO_DECL bool is_loopback() const noexcept;+  ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT;    /// Determine whether the address is unspecified.-  ASIO_DECL bool is_unspecified() const noexcept;+  ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT;    /// Determine whether the address is a multicast address.-  ASIO_DECL bool is_multicast() const noexcept;+  ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT;    /// Compare two addresses for equality.   ASIO_DECL friend bool operator==(const address& a1,-      const address& a2) noexcept;+      const address& a2) ASIO_NOEXCEPT;    /// Compare two addresses for inequality.   friend bool operator!=(const address& a1,-      const address& a2) noexcept+      const address& a2) ASIO_NOEXCEPT   {     return !(a1 == a2);   }    /// Compare addresses for ordering.   ASIO_DECL friend bool operator<(const address& a1,-      const address& a2) noexcept;+      const address& a2) ASIO_NOEXCEPT;    /// Compare addresses for ordering.   friend bool operator>(const address& a1,-      const address& a2) noexcept+      const address& a2) ASIO_NOEXCEPT   {     return a2 < a1;   }    /// Compare addresses for ordering.   friend bool operator<=(const address& a1,-      const address& a2) noexcept+      const address& a2) ASIO_NOEXCEPT   {     return !(a2 < a1);   }    /// Compare addresses for ordering.   friend bool operator>=(const address& a1,-      const address& a2) noexcept+      const address& a2) ASIO_NOEXCEPT   {     return !(a1 < a2);   }@@ -168,7 +201,7 @@  * @relates address  */ ASIO_DECL address make_address(const char* str,-    asio::error_code& ec) noexcept;+    asio::error_code& ec) ASIO_NOEXCEPT;  /// Create an address from an IPv4 address string in dotted decimal form, /// or from an IPv6 address in hexadecimal notation.@@ -183,7 +216,7 @@  * @relates address  */ ASIO_DECL address make_address(const std::string& str,-    asio::error_code& ec) noexcept;+    asio::error_code& ec) ASIO_NOEXCEPT;  #if defined(ASIO_HAS_STRING_VIEW) \   || defined(GENERATING_DOCUMENTATION)@@ -201,7 +234,7 @@  * @relates address  */ ASIO_DECL address make_address(string_view str,-    asio::error_code& ec) noexcept;+    asio::error_code& ec) ASIO_NOEXCEPT;  #endif // defined(ASIO_HAS_STRING_VIEW)        //  || defined(GENERATING_DOCUMENTATION)@@ -229,13 +262,14 @@ } // namespace ip } // namespace asio +#if defined(ASIO_HAS_STD_HASH) namespace std {  template <> struct hash<asio::ip::address> {   std::size_t operator()(const asio::ip::address& addr)-    const noexcept+    const ASIO_NOEXCEPT   {     return addr.is_v4()       ? std::hash<asio::ip::address_v4>()(addr.to_v4())@@ -244,6 +278,7 @@ };  } // namespace std+#endif // defined(ASIO_HAS_STD_HASH)  #include "asio/detail/pop_options.hpp" 
link/modules/asio-standalone/asio/include/asio/ip/address_v4.hpp view
@@ -2,7 +2,7 @@ // ip/address_v4.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,7 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <functional> #include <string> #include "asio/detail/array.hpp" #include "asio/detail/cstdint.hpp"@@ -25,6 +24,10 @@ #include "asio/detail/winsock_init.hpp" #include "asio/error_code.hpp" +#if defined(ASIO_HAS_STD_HASH)+# include <functional>+#endif // defined(ASIO_HAS_STD_HASH)+ #if !defined(ASIO_NO_IOSTREAM) # include <iosfwd> #endif // !defined(ASIO_NO_IOSTREAM)@@ -66,7 +69,7 @@    * @li <tt>to_bytes()</tt> yields <tt>{0, 0, 0, 0}</tt>; and    * @li <tt>to_uint() == 0</tt>.    */-  address_v4() noexcept+  address_v4() ASIO_NOEXCEPT   {     addr_.s_addr = 0;   }@@ -89,40 +92,74 @@   ASIO_DECL explicit address_v4(uint_type addr);    /// Copy constructor.-  address_v4(const address_v4& other) noexcept+  address_v4(const address_v4& other) ASIO_NOEXCEPT     : addr_(other.addr_)   {   } +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  address_v4(address_v4&& other) noexcept+  address_v4(address_v4&& other) ASIO_NOEXCEPT     : addr_(other.addr_)   {   }+#endif // defined(ASIO_HAS_MOVE)    /// Assign from another address.-  address_v4& operator=(const address_v4& other) noexcept+  address_v4& operator=(const address_v4& other) ASIO_NOEXCEPT   {     addr_ = other.addr_;     return *this;   } +#if defined(ASIO_HAS_MOVE)   /// Move-assign from another address.-  address_v4& operator=(address_v4&& other) noexcept+  address_v4& operator=(address_v4&& other) ASIO_NOEXCEPT   {     addr_ = other.addr_;     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    /// Get the address in bytes, in network byte order.-  ASIO_DECL bytes_type to_bytes() const noexcept;+  ASIO_DECL bytes_type to_bytes() const ASIO_NOEXCEPT;    /// Get the address as an unsigned integer in host byte order.-  ASIO_DECL uint_type to_uint() const noexcept;+  ASIO_DECL uint_type to_uint() const ASIO_NOEXCEPT; +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use to_uint().) Get the address as an unsigned long in host+  /// byte order.+  ASIO_DECL unsigned long to_ulong() const;+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Get the address as a string in dotted decimal format.   ASIO_DECL std::string to_string() const; +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use other overload.) Get the address as a string in dotted+  /// decimal format.+  ASIO_DECL std::string to_string(asio::error_code& ec) const;++  /// (Deprecated: Use make_address_v4().) Create an address from an IP address+  /// string in dotted decimal form.+  static address_v4 from_string(const char* str);++  /// (Deprecated: Use make_address_v4().) Create an address from an IP address+  /// string in dotted decimal form.+  static address_v4 from_string(+      const char* str, asio::error_code& ec);++  /// (Deprecated: Use make_address_v4().) Create an address from an IP address+  /// string in dotted decimal form.+  static address_v4 from_string(const std::string& str);++  /// (Deprecated: Use make_address_v4().) Create an address from an IP address+  /// string in dotted decimal form.+  static address_v4 from_string(+      const std::string& str, asio::error_code& ec);+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Determine whether the address is a loopback address.   /**    * This function tests whether the address is in the address block@@ -131,7 +168,7 @@    *    * @returns <tt>(to_uint() & 0xFF000000) == 0x7F000000</tt>.    */-  ASIO_DECL bool is_loopback() const noexcept;+  ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT;    /// Determine whether the address is unspecified.   /**@@ -140,8 +177,22 @@    *    * @returns <tt>to_uint() == 0</tt>.    */-  ASIO_DECL bool is_unspecified() const noexcept;+  ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT; +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use network_v4 class.) Determine whether the address is a+  /// class A address.+  ASIO_DECL bool is_class_a() const;++  /// (Deprecated: Use network_v4 class.) Determine whether the address is a+  /// class B address.+  ASIO_DECL bool is_class_b() const;++  /// (Deprecated: Use network_v4 class.) Determine whether the address is a+  /// class C address.+  ASIO_DECL bool is_class_c() const;+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Determine whether the address is a multicast address.   /**    * This function tests whether the address is in the multicast address block@@ -150,18 +201,18 @@    *    * @returns <tt>(to_uint() & 0xF0000000) == 0xE0000000</tt>.    */-  ASIO_DECL bool is_multicast() const noexcept;+  ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT;    /// Compare two addresses for equality.   friend bool operator==(const address_v4& a1,-      const address_v4& a2) noexcept+      const address_v4& a2) ASIO_NOEXCEPT   {     return a1.addr_.s_addr == a2.addr_.s_addr;   }    /// Compare two addresses for inequality.   friend bool operator!=(const address_v4& a1,-      const address_v4& a2) noexcept+      const address_v4& a2) ASIO_NOEXCEPT   {     return a1.addr_.s_addr != a2.addr_.s_addr;   }@@ -173,7 +224,7 @@    * @returns <tt>a1.to_uint() < a2.to_uint()</tt>.    */   friend bool operator<(const address_v4& a1,-      const address_v4& a2) noexcept+      const address_v4& a2) ASIO_NOEXCEPT   {     return a1.to_uint() < a2.to_uint();   }@@ -185,7 +236,7 @@    * @returns <tt>a1.to_uint() > a2.to_uint()</tt>.    */   friend bool operator>(const address_v4& a1,-      const address_v4& a2) noexcept+      const address_v4& a2) ASIO_NOEXCEPT   {     return a1.to_uint() > a2.to_uint();   }@@ -197,7 +248,7 @@    * @returns <tt>a1.to_uint() <= a2.to_uint()</tt>.    */   friend bool operator<=(const address_v4& a1,-      const address_v4& a2) noexcept+      const address_v4& a2) ASIO_NOEXCEPT   {     return a1.to_uint() <= a2.to_uint();   }@@ -209,7 +260,7 @@    * @returns <tt>a1.to_uint() >= a2.to_uint()</tt>.    */   friend bool operator>=(const address_v4& a1,-      const address_v4& a2) noexcept+      const address_v4& a2) ASIO_NOEXCEPT   {     return a1.to_uint() >= a2.to_uint();   }@@ -221,7 +272,7 @@    *    * @returns A default-constructed @c address_v4 object.    */-  static address_v4 any() noexcept+  static address_v4 any() ASIO_NOEXCEPT   {     return address_v4();   }@@ -233,7 +284,7 @@    *    * @returns <tt>address_v4(0x7F000001)</tt>.    */-  static address_v4 loopback() noexcept+  static address_v4 loopback() ASIO_NOEXCEPT   {     return address_v4(0x7F000001);   }@@ -245,11 +296,23 @@    *    * @returns <tt>address_v4(0xFFFFFFFF)</tt>.    */-  static address_v4 broadcast() noexcept+  static address_v4 broadcast() ASIO_NOEXCEPT   {     return address_v4(0xFFFFFFFF);   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use network_v4 class.) Obtain an address object that+  /// represents the broadcast address that corresponds to the specified+  /// address and netmask.+  ASIO_DECL static address_v4 broadcast(+      const address_v4& addr, const address_v4& mask);++  /// (Deprecated: Use network_v4 class.) Obtain the netmask that corresponds+  /// to the address, based on its address class.+  ASIO_DECL static address_v4 netmask(const address_v4& addr);+#endif // !defined(ASIO_NO_DEPRECATED)+ private:   // The underlying IPv4 address.   asio::detail::in4_addr_type addr_;@@ -284,7 +347,7 @@  * @relates address_v4  */ ASIO_DECL address_v4 make_address_v4(const char* str,-    asio::error_code& ec) noexcept;+    asio::error_code& ec) ASIO_NOEXCEPT;  /// Create an IPv4 address from an IP address string in dotted decimal form. /**@@ -297,7 +360,7 @@  * @relates address_v4  */ ASIO_DECL address_v4 make_address_v4(const std::string& str,-    asio::error_code& ec) noexcept;+    asio::error_code& ec) ASIO_NOEXCEPT;  #if defined(ASIO_HAS_STRING_VIEW) \   || defined(GENERATING_DOCUMENTATION)@@ -313,7 +376,7 @@  * @relates address_v4  */ ASIO_DECL address_v4 make_address_v4(string_view str,-    asio::error_code& ec) noexcept;+    asio::error_code& ec) ASIO_NOEXCEPT;  #endif // defined(ASIO_HAS_STRING_VIEW)        //  || defined(GENERATING_DOCUMENTATION)@@ -341,19 +404,21 @@ } // namespace ip } // namespace asio +#if defined(ASIO_HAS_STD_HASH) namespace std {  template <> struct hash<asio::ip::address_v4> {   std::size_t operator()(const asio::ip::address_v4& addr)-    const noexcept+    const ASIO_NOEXCEPT   {     return std::hash<unsigned int>()(addr.to_uint());   } };  } // namespace std+#endif // defined(ASIO_HAS_STD_HASH)  #include "asio/detail/pop_options.hpp" 
link/modules/asio-standalone/asio/include/asio/ip/address_v4_iterator.hpp view
@@ -2,7 +2,7 @@ // ip/address_v4_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -53,59 +53,65 @@   typedef std::input_iterator_tag iterator_category;    /// Construct an iterator that points to the specified address.-  basic_address_iterator(const address_v4& addr) noexcept+  basic_address_iterator(const address_v4& addr) ASIO_NOEXCEPT     : address_(addr)   {   }    /// Copy constructor.-  basic_address_iterator(const basic_address_iterator& other) noexcept+  basic_address_iterator(+      const basic_address_iterator& other) ASIO_NOEXCEPT     : address_(other.address_)   {   } +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  basic_address_iterator(basic_address_iterator&& other) noexcept-    : address_(static_cast<address_v4&&>(other.address_))+  basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT+    : address_(ASIO_MOVE_CAST(address_v4)(other.address_))   {   }+#endif // defined(ASIO_HAS_MOVE)    /// Assignment operator.   basic_address_iterator& operator=(-      const basic_address_iterator& other) noexcept+      const basic_address_iterator& other) ASIO_NOEXCEPT   {     address_ = other.address_;     return *this;   } +#if defined(ASIO_HAS_MOVE)   /// Move assignment operator.-  basic_address_iterator& operator=(basic_address_iterator&& other) noexcept+  basic_address_iterator& operator=(+      basic_address_iterator&& other) ASIO_NOEXCEPT   {-    address_ = static_cast<address_v4&&>(other.address_);+    address_ = ASIO_MOVE_CAST(address_v4)(other.address_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    /// Dereference the iterator.-  const address_v4& operator*() const noexcept+  const address_v4& operator*() const ASIO_NOEXCEPT   {     return address_;   }    /// Dereference the iterator.-  const address_v4* operator->() const noexcept+  const address_v4* operator->() const ASIO_NOEXCEPT   {     return &address_;   }    /// Pre-increment operator.-  basic_address_iterator& operator++() noexcept+  basic_address_iterator& operator++() ASIO_NOEXCEPT   {     address_ = address_v4((address_.to_uint() + 1) & 0xFFFFFFFF);     return *this;   }    /// Post-increment operator.-  basic_address_iterator operator++(int) noexcept+  basic_address_iterator operator++(int) ASIO_NOEXCEPT   {     basic_address_iterator tmp(*this);     ++*this;@@ -113,7 +119,7 @@   }    /// Pre-decrement operator.-  basic_address_iterator& operator--() noexcept+  basic_address_iterator& operator--() ASIO_NOEXCEPT   {     address_ = address_v4((address_.to_uint() - 1) & 0xFFFFFFFF);     return *this;
link/modules/asio-standalone/asio/include/asio/ip/address_v4_range.hpp view
@@ -2,7 +2,7 @@ // ip/address_v4_range.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -38,7 +38,7 @@   typedef basic_address_iterator<address_v4> iterator;    /// Construct an empty range.-  basic_address_range() noexcept+  basic_address_range() ASIO_NOEXCEPT     : begin_(address_v4()),       end_(address_v4())   {@@ -46,68 +46,74 @@    /// Construct an range that represents the given range of addresses.   explicit basic_address_range(const iterator& first,-      const iterator& last) noexcept+      const iterator& last) ASIO_NOEXCEPT     : begin_(first),       end_(last)   {   }    /// Copy constructor.-  basic_address_range(const basic_address_range& other) noexcept+  basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT     : begin_(other.begin_),       end_(other.end_)   {   } +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  basic_address_range(basic_address_range&& other) noexcept-    : begin_(static_cast<iterator&&>(other.begin_)),-      end_(static_cast<iterator&&>(other.end_))+  basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT+    : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)),+      end_(ASIO_MOVE_CAST(iterator)(other.end_))   {   }+#endif // defined(ASIO_HAS_MOVE)    /// Assignment operator.-  basic_address_range& operator=(const basic_address_range& other) noexcept+  basic_address_range& operator=(+      const basic_address_range& other) ASIO_NOEXCEPT   {     begin_ = other.begin_;     end_ = other.end_;     return *this;   } +#if defined(ASIO_HAS_MOVE)   /// Move assignment operator.-  basic_address_range& operator=(basic_address_range&& other) noexcept+  basic_address_range& operator=(+      basic_address_range&& other) ASIO_NOEXCEPT   {-    begin_ = static_cast<iterator&&>(other.begin_);-    end_ = static_cast<iterator&&>(other.end_);+    begin_ = ASIO_MOVE_CAST(iterator)(other.begin_);+    end_ = ASIO_MOVE_CAST(iterator)(other.end_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    /// Obtain an iterator that points to the start of the range.-  iterator begin() const noexcept+  iterator begin() const ASIO_NOEXCEPT   {     return begin_;   }    /// Obtain an iterator that points to the end of the range.-  iterator end() const noexcept+  iterator end() const ASIO_NOEXCEPT   {     return end_;   }    /// Determine whether the range is empty.-  bool empty() const noexcept+  bool empty() const ASIO_NOEXCEPT   {     return size() == 0;   }    /// Return the size of the range.-  std::size_t size() const noexcept+  std::size_t size() const ASIO_NOEXCEPT   {     return end_->to_uint() - begin_->to_uint();   }    /// Find an address in the range.-  iterator find(const address_v4& addr) const noexcept+  iterator find(const address_v4& addr) const ASIO_NOEXCEPT   {     return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_;   }
link/modules/asio-standalone/asio/include/asio/ip/address_v6.hpp view
@@ -2,7 +2,7 @@ // ip/address_v6.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,7 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <functional> #include <string> #include "asio/detail/array.hpp" #include "asio/detail/cstdint.hpp"@@ -26,6 +25,10 @@ #include "asio/error_code.hpp" #include "asio/ip/address_v4.hpp" +#if defined(ASIO_HAS_STD_HASH)+# include <functional>+#endif // defined(ASIO_HAS_STD_HASH)+ #if !defined(ASIO_NO_IOSTREAM) # include <iosfwd> #endif // !defined(ASIO_NO_IOSTREAM)@@ -69,7 +72,7 @@    * @li <tt>to_bytes()</tt> yields <tt>{0, 0, ..., 0}</tt>; and    * @li <tt>scope_id() == 0</tt>.    */-  ASIO_DECL address_v6() noexcept;+  ASIO_DECL address_v6() ASIO_NOEXCEPT;    /// Construct an address from raw bytes and scope ID.   /**@@ -85,23 +88,27 @@       scope_id_type scope_id = 0);    /// Copy constructor.-  ASIO_DECL address_v6(const address_v6& other) noexcept;+  ASIO_DECL address_v6(const address_v6& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  ASIO_DECL address_v6(address_v6&& other) noexcept;+  ASIO_DECL address_v6(address_v6&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE)    /// Assign from another address.   ASIO_DECL address_v6& operator=(-      const address_v6& other) noexcept;+      const address_v6& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE)   /// Move-assign from another address.-  ASIO_DECL address_v6& operator=(address_v6&& other) noexcept;+  ASIO_DECL address_v6& operator=(address_v6&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE)    /// The scope ID of the address.   /**    * Returns the scope ID associated with the IPv6 address.    */-  scope_id_type scope_id() const noexcept+  scope_id_type scope_id() const ASIO_NOEXCEPT   {     return scope_id_;   }@@ -112,90 +119,123 @@    *    * @param id The new scope ID.    */-  void scope_id(scope_id_type id) noexcept+  void scope_id(scope_id_type id) ASIO_NOEXCEPT   {     scope_id_ = id;   }    /// Get the address in bytes, in network byte order.-  ASIO_DECL bytes_type to_bytes() const noexcept;+  ASIO_DECL bytes_type to_bytes() const ASIO_NOEXCEPT;    /// Get the address as a string.   ASIO_DECL std::string to_string() const; +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use other overload.) Get the address as a string.+  ASIO_DECL std::string to_string(asio::error_code& ec) const;++  /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP+  /// address string.+  static address_v6 from_string(const char* str);++  /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP+  /// address string.+  static address_v6 from_string(+      const char* str, asio::error_code& ec);++  /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP+  /// address string.+  static address_v6 from_string(const std::string& str);++  /// (Deprecated: Use make_address_v6().) Create an IPv6 address from an IP+  /// address string.+  static address_v6 from_string(+      const std::string& str, asio::error_code& ec);++  /// (Deprecated: Use make_address_v4().) Converts an IPv4-mapped or+  /// IPv4-compatible address to an IPv4 address.+  ASIO_DECL address_v4 to_v4() const;+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Determine whether the address is a loopback address.   /**    * This function tests whether the address is the loopback address    * <tt>::1</tt>.    */-  ASIO_DECL bool is_loopback() const noexcept;+  ASIO_DECL bool is_loopback() const ASIO_NOEXCEPT;    /// Determine whether the address is unspecified.   /**    * This function tests whether the address is the loopback address    * <tt>::</tt>.    */-  ASIO_DECL bool is_unspecified() const noexcept;+  ASIO_DECL bool is_unspecified() const ASIO_NOEXCEPT;    /// Determine whether the address is link local.-  ASIO_DECL bool is_link_local() const noexcept;+  ASIO_DECL bool is_link_local() const ASIO_NOEXCEPT;    /// Determine whether the address is site local.-  ASIO_DECL bool is_site_local() const noexcept;+  ASIO_DECL bool is_site_local() const ASIO_NOEXCEPT;    /// Determine whether the address is a mapped IPv4 address.-  ASIO_DECL bool is_v4_mapped() const noexcept;+  ASIO_DECL bool is_v4_mapped() const ASIO_NOEXCEPT; +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: No replacement.) Determine whether the address is an+  /// IPv4-compatible address.+  ASIO_DECL bool is_v4_compatible() const;+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Determine whether the address is a multicast address.-  ASIO_DECL bool is_multicast() const noexcept;+  ASIO_DECL bool is_multicast() const ASIO_NOEXCEPT;    /// Determine whether the address is a global multicast address.-  ASIO_DECL bool is_multicast_global() const noexcept;+  ASIO_DECL bool is_multicast_global() const ASIO_NOEXCEPT;    /// Determine whether the address is a link-local multicast address.-  ASIO_DECL bool is_multicast_link_local() const noexcept;+  ASIO_DECL bool is_multicast_link_local() const ASIO_NOEXCEPT;    /// Determine whether the address is a node-local multicast address.-  ASIO_DECL bool is_multicast_node_local() const noexcept;+  ASIO_DECL bool is_multicast_node_local() const ASIO_NOEXCEPT;    /// Determine whether the address is a org-local multicast address.-  ASIO_DECL bool is_multicast_org_local() const noexcept;+  ASIO_DECL bool is_multicast_org_local() const ASIO_NOEXCEPT;    /// Determine whether the address is a site-local multicast address.-  ASIO_DECL bool is_multicast_site_local() const noexcept;+  ASIO_DECL bool is_multicast_site_local() const ASIO_NOEXCEPT;    /// Compare two addresses for equality.   ASIO_DECL friend bool operator==(const address_v6& a1,-      const address_v6& a2) noexcept;+      const address_v6& a2) ASIO_NOEXCEPT;    /// Compare two addresses for inequality.   friend bool operator!=(const address_v6& a1,-      const address_v6& a2) noexcept+      const address_v6& a2) ASIO_NOEXCEPT   {     return !(a1 == a2);   }    /// Compare addresses for ordering.   ASIO_DECL friend bool operator<(const address_v6& a1,-      const address_v6& a2) noexcept;+      const address_v6& a2) ASIO_NOEXCEPT;    /// Compare addresses for ordering.   friend bool operator>(const address_v6& a1,-      const address_v6& a2) noexcept+      const address_v6& a2) ASIO_NOEXCEPT   {     return a2 < a1;   }    /// Compare addresses for ordering.   friend bool operator<=(const address_v6& a1,-      const address_v6& a2) noexcept+      const address_v6& a2) ASIO_NOEXCEPT   {     return !(a2 < a1);   }    /// Compare addresses for ordering.   friend bool operator>=(const address_v6& a1,-      const address_v6& a2) noexcept+      const address_v6& a2) ASIO_NOEXCEPT   {     return !(a1 < a2);   }@@ -207,7 +247,7 @@    *    * @returns A default-constructed @c address_v6 object.    */-  static address_v6 any() noexcept+  static address_v6 any() ASIO_NOEXCEPT   {     return address_v6();   }@@ -217,8 +257,16 @@    * This function returns an address that represents the well-known loopback    * address <tt>::1</tt>.    */-  ASIO_DECL static address_v6 loopback() noexcept;+  ASIO_DECL static address_v6 loopback() ASIO_NOEXCEPT; +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address.+  ASIO_DECL static address_v6 v4_mapped(const address_v4& addr);++  /// (Deprecated: No replacement.) Create an IPv4-compatible IPv6 address.+  ASIO_DECL static address_v6 v4_compatible(const address_v4& addr);+#endif // !defined(ASIO_NO_DEPRECATED)+ private:   friend class basic_address_iterator<address_v6>; @@ -250,7 +298,7 @@  * @relates address_v6  */ ASIO_DECL address_v6 make_address_v6(const char* str,-    asio::error_code& ec) noexcept;+    asio::error_code& ec) ASIO_NOEXCEPT;  /// Createan IPv6 address from an IP address string. /**@@ -263,7 +311,7 @@  * @relates address_v6  */ ASIO_DECL address_v6 make_address_v6(const std::string& str,-    asio::error_code& ec) noexcept;+    asio::error_code& ec) ASIO_NOEXCEPT;  #if defined(ASIO_HAS_STRING_VIEW) \   || defined(GENERATING_DOCUMENTATION)@@ -279,7 +327,7 @@  * @relates address_v6  */ ASIO_DECL address_v6 make_address_v6(string_view str,-    asio::error_code& ec) noexcept;+    asio::error_code& ec) ASIO_NOEXCEPT;  #endif // defined(ASIO_HAS_STRING_VIEW)        //  || defined(GENERATING_DOCUMENTATION)@@ -325,13 +373,14 @@ } // namespace ip } // namespace asio +#if defined(ASIO_HAS_STD_HASH) namespace std {  template <> struct hash<asio::ip::address_v6> {   std::size_t operator()(const asio::ip::address_v6& addr)-    const noexcept+    const ASIO_NOEXCEPT   {     const asio::ip::address_v6::bytes_type bytes = addr.to_bytes();     std::size_t result = static_cast<std::size_t>(addr.scope_id());@@ -355,6 +404,7 @@ };  } // namespace std+#endif // defined(ASIO_HAS_STD_HASH)  #include "asio/detail/pop_options.hpp" 
link/modules/asio-standalone/asio/include/asio/ip/address_v6_iterator.hpp view
@@ -2,7 +2,7 @@ // ip/address_v6_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) //                         Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -54,53 +54,58 @@   typedef std::input_iterator_tag iterator_category;    /// Construct an iterator that points to the specified address.-  basic_address_iterator(const address_v6& addr) noexcept+  basic_address_iterator(const address_v6& addr) ASIO_NOEXCEPT     : address_(addr)   {   }    /// Copy constructor.   basic_address_iterator(-      const basic_address_iterator& other) noexcept+      const basic_address_iterator& other) ASIO_NOEXCEPT     : address_(other.address_)   {   } +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  basic_address_iterator(basic_address_iterator&& other) noexcept-    : address_(static_cast<address_v6&&>(other.address_))+  basic_address_iterator(basic_address_iterator&& other) ASIO_NOEXCEPT+    : address_(ASIO_MOVE_CAST(address_v6)(other.address_))   {   }+#endif // defined(ASIO_HAS_MOVE)    /// Assignment operator.   basic_address_iterator& operator=(-      const basic_address_iterator& other) noexcept+      const basic_address_iterator& other) ASIO_NOEXCEPT   {     address_ = other.address_;     return *this;   } +#if defined(ASIO_HAS_MOVE)   /// Move assignment operator.-  basic_address_iterator& operator=(basic_address_iterator&& other) noexcept+  basic_address_iterator& operator=(+      basic_address_iterator&& other) ASIO_NOEXCEPT   {-    address_ = static_cast<address_v6&&>(other.address_);+    address_ = ASIO_MOVE_CAST(address_v6)(other.address_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    /// Dereference the iterator.-  const address_v6& operator*() const noexcept+  const address_v6& operator*() const ASIO_NOEXCEPT   {     return address_;   }    /// Dereference the iterator.-  const address_v6* operator->() const noexcept+  const address_v6* operator->() const ASIO_NOEXCEPT   {     return &address_;   }    /// Pre-increment operator.-  basic_address_iterator& operator++() noexcept+  basic_address_iterator& operator++() ASIO_NOEXCEPT   {     for (int i = 15; i >= 0; --i)     {@@ -117,7 +122,7 @@   }    /// Post-increment operator.-  basic_address_iterator operator++(int) noexcept+  basic_address_iterator operator++(int) ASIO_NOEXCEPT   {     basic_address_iterator tmp(*this);     ++*this;@@ -125,7 +130,7 @@   }    /// Pre-decrement operator.-  basic_address_iterator& operator--() noexcept+  basic_address_iterator& operator--() ASIO_NOEXCEPT   {     for (int i = 15; i >= 0; --i)     {
link/modules/asio-standalone/asio/include/asio/ip/address_v6_range.hpp view
@@ -2,7 +2,7 @@ // ip/address_v6_range.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) //                         Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -39,7 +39,7 @@   typedef basic_address_iterator<address_v6> iterator;    /// Construct an empty range.-  basic_address_range() noexcept+  basic_address_range() ASIO_NOEXCEPT     : begin_(address_v6()),       end_(address_v6())   {@@ -47,63 +47,68 @@    /// Construct an range that represents the given range of addresses.   explicit basic_address_range(const iterator& first,-      const iterator& last) noexcept+      const iterator& last) ASIO_NOEXCEPT     : begin_(first),       end_(last)   {   }    /// Copy constructor.-  basic_address_range(const basic_address_range& other) noexcept+  basic_address_range(const basic_address_range& other) ASIO_NOEXCEPT     : begin_(other.begin_),       end_(other.end_)   {   } +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  basic_address_range(basic_address_range&& other) noexcept-    : begin_(static_cast<iterator&&>(other.begin_)),-      end_(static_cast<iterator&&>(other.end_))+  basic_address_range(basic_address_range&& other) ASIO_NOEXCEPT+    : begin_(ASIO_MOVE_CAST(iterator)(other.begin_)),+      end_(ASIO_MOVE_CAST(iterator)(other.end_))   {   }+#endif // defined(ASIO_HAS_MOVE)    /// Assignment operator.   basic_address_range& operator=(-      const basic_address_range& other) noexcept+      const basic_address_range& other) ASIO_NOEXCEPT   {     begin_ = other.begin_;     end_ = other.end_;     return *this;   } +#if defined(ASIO_HAS_MOVE)   /// Move assignment operator.-  basic_address_range& operator=(basic_address_range&& other) noexcept+  basic_address_range& operator=(+      basic_address_range&& other) ASIO_NOEXCEPT   {-    begin_ = static_cast<iterator&&>(other.begin_);-    end_ = static_cast<iterator&&>(other.end_);+    begin_ = ASIO_MOVE_CAST(iterator)(other.begin_);+    end_ = ASIO_MOVE_CAST(iterator)(other.end_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    /// Obtain an iterator that points to the start of the range.-  iterator begin() const noexcept+  iterator begin() const ASIO_NOEXCEPT   {     return begin_;   }    /// Obtain an iterator that points to the end of the range.-  iterator end() const noexcept+  iterator end() const ASIO_NOEXCEPT   {     return end_;   }    /// Determine whether the range is empty.-  bool empty() const noexcept+  bool empty() const ASIO_NOEXCEPT   {     return begin_ == end_;   }    /// Find an address in the range.-  iterator find(const address_v6& addr) const noexcept+  iterator find(const address_v6& addr) const ASIO_NOEXCEPT   {     return addr >= *begin_ && addr < *end_ ? iterator(addr) : end_;   }
link/modules/asio-standalone/asio/include/asio/ip/bad_address_cast.hpp view
@@ -2,7 +2,7 @@ // ip/bad_address_cast.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -35,21 +35,11 @@   /// Default constructor.   bad_address_cast() {} -  /// Copy constructor.-  bad_address_cast(const bad_address_cast& other) noexcept-#if defined(ASIO_MSVC) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS-    : std::exception(static_cast<const std::exception&>(other))-#else-    : std::bad_cast(static_cast<const std::bad_cast&>(other))-#endif-  {-  }-   /// Destructor.-  virtual ~bad_address_cast() noexcept {}+  virtual ~bad_address_cast() ASIO_NOEXCEPT_OR_NOTHROW {}    /// Get the message associated with the exception.-  virtual const char* what() const noexcept+  virtual const char* what() const ASIO_NOEXCEPT_OR_NOTHROW   {     return "bad address cast";   }
link/modules/asio-standalone/asio/include/asio/ip/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // ip/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,11 +16,14 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <functional> #include "asio/detail/cstdint.hpp" #include "asio/ip/address.hpp" #include "asio/ip/detail/endpoint.hpp" +#if defined(ASIO_HAS_STD_HASH)+# include <functional>+#endif // defined(ASIO_HAS_STD_HASH)+ #if !defined(ASIO_NO_IOSTREAM) # include <iosfwd> #endif // !defined(ASIO_NO_IOSTREAM)@@ -61,7 +64,7 @@ #endif    /// Default constructor.-  basic_endpoint() noexcept+  basic_endpoint() ASIO_NOEXCEPT     : impl_()   {   }@@ -83,7 +86,7 @@    * @endcode    */   basic_endpoint(const InternetProtocol& internet_protocol,-      port_type port_num) noexcept+      port_type port_num) ASIO_NOEXCEPT     : impl_(internet_protocol.family(), port_num)   {   }@@ -92,39 +95,43 @@   /// constructor may be used for accepting connections on a specific interface   /// or for making a connection to a remote endpoint.   basic_endpoint(const asio::ip::address& addr,-      port_type port_num) noexcept+      port_type port_num) ASIO_NOEXCEPT     : impl_(addr, port_num)   {   }    /// Copy constructor.-  basic_endpoint(const basic_endpoint& other) noexcept+  basic_endpoint(const basic_endpoint& other) ASIO_NOEXCEPT     : impl_(other.impl_)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.-  basic_endpoint(basic_endpoint&& other) noexcept+  basic_endpoint(basic_endpoint&& other) ASIO_NOEXCEPT     : impl_(other.impl_)   {   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Assign from another endpoint.-  basic_endpoint& operator=(const basic_endpoint& other) noexcept+  basic_endpoint& operator=(const basic_endpoint& other) ASIO_NOEXCEPT   {     impl_ = other.impl_;     return *this;   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-assign from another endpoint.-  basic_endpoint& operator=(basic_endpoint&& other) noexcept+  basic_endpoint& operator=(basic_endpoint&& other) ASIO_NOEXCEPT   {     impl_ = other.impl_;     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// The protocol associated with the endpoint.-  protocol_type protocol() const noexcept+  protocol_type protocol() const ASIO_NOEXCEPT   {     if (impl_.is_v4())       return InternetProtocol::v4();@@ -132,19 +139,19 @@   }    /// Get the underlying endpoint in the native type.-  data_type* data() noexcept+  data_type* data() ASIO_NOEXCEPT   {     return impl_.data();   }    /// Get the underlying endpoint in the native type.-  const data_type* data() const noexcept+  const data_type* data() const ASIO_NOEXCEPT   {     return impl_.data();   }    /// Get the underlying size of the endpoint in the native type.-  std::size_t size() const noexcept+  std::size_t size() const ASIO_NOEXCEPT   {     return impl_.size();   }@@ -156,75 +163,75 @@   }    /// Get the capacity of the endpoint in the native type.-  std::size_t capacity() const noexcept+  std::size_t capacity() const ASIO_NOEXCEPT   {     return impl_.capacity();   }    /// Get the port associated with the endpoint. The port number is always in   /// the host's byte order.-  port_type port() const noexcept+  port_type port() const ASIO_NOEXCEPT   {     return impl_.port();   }    /// Set the port associated with the endpoint. The port number is always in   /// the host's byte order.-  void port(port_type port_num) noexcept+  void port(port_type port_num) ASIO_NOEXCEPT   {     impl_.port(port_num);   }    /// Get the IP address associated with the endpoint.-  asio::ip::address address() const noexcept+  asio::ip::address address() const ASIO_NOEXCEPT   {     return impl_.address();   }    /// Set the IP address associated with the endpoint.-  void address(const asio::ip::address& addr) noexcept+  void address(const asio::ip::address& addr) ASIO_NOEXCEPT   {     impl_.address(addr);   }    /// Compare two endpoints for equality.   friend bool operator==(const basic_endpoint<InternetProtocol>& e1,-      const basic_endpoint<InternetProtocol>& e2) noexcept+      const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT   {     return e1.impl_ == e2.impl_;   }    /// Compare two endpoints for inequality.   friend bool operator!=(const basic_endpoint<InternetProtocol>& e1,-      const basic_endpoint<InternetProtocol>& e2) noexcept+      const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT   {     return !(e1 == e2);   }    /// Compare endpoints for ordering.   friend bool operator<(const basic_endpoint<InternetProtocol>& e1,-      const basic_endpoint<InternetProtocol>& e2) noexcept+      const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT   {     return e1.impl_ < e2.impl_;   }    /// Compare endpoints for ordering.   friend bool operator>(const basic_endpoint<InternetProtocol>& e1,-      const basic_endpoint<InternetProtocol>& e2) noexcept+      const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT   {     return e2.impl_ < e1.impl_;   }    /// Compare endpoints for ordering.   friend bool operator<=(const basic_endpoint<InternetProtocol>& e1,-      const basic_endpoint<InternetProtocol>& e2) noexcept+      const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT   {     return !(e2 < e1);   }    /// Compare endpoints for ordering.   friend bool operator>=(const basic_endpoint<InternetProtocol>& e1,-      const basic_endpoint<InternetProtocol>& e2) noexcept+      const basic_endpoint<InternetProtocol>& e2) ASIO_NOEXCEPT   {     return !(e1 < e2);   }@@ -258,14 +265,15 @@ } // namespace ip } // namespace asio +#if defined(ASIO_HAS_STD_HASH) namespace std {  template <typename InternetProtocol>-struct hash<asio::ip::basic_endpoint<InternetProtocol>>+struct hash<asio::ip::basic_endpoint<InternetProtocol> > {   std::size_t operator()(       const asio::ip::basic_endpoint<InternetProtocol>& ep)-    const noexcept+    const ASIO_NOEXCEPT   {     std::size_t hash1 = std::hash<asio::ip::address>()(ep.address());     std::size_t hash2 = std::hash<unsigned short>()(ep.port());@@ -274,6 +282,7 @@ };  } // namespace std+#endif // defined(ASIO_HAS_STD_HASH)  #include "asio/detail/pop_options.hpp" 
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,7 +17,6 @@  #include "asio/detail/config.hpp" #include <string>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -37,6 +36,10 @@ # include "asio/detail/resolver_service.hpp" #endif +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -85,6 +88,14 @@   /// The endpoint type.   typedef typename InternetProtocol::endpoint endpoint_type; +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated.) The query type.+  typedef basic_resolver_query<InternetProtocol> query;++  /// (Deprecated.) The iterator type.+  typedef basic_resolver_iterator<InternetProtocol> iterator;+#endif // !defined(ASIO_NO_DEPRECATED)+   /// The results type.   typedef basic_resolver_results<InternetProtocol> results_type; @@ -111,13 +122,14 @@    */   template <typename ExecutionContext>   explicit basic_resolver(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a basic_resolver from another.   /**    * This constructor moves a resolver from one object to another.@@ -149,9 +161,9 @@    */   template <typename Executor1>   basic_resolver(basic_resolver<InternetProtocol, Executor1>&& other,-      constraint_t<+      typename constraint<           is_convertible<Executor1, Executor>::value-      > = 0)+      >::type = 0)     : impl_(std::move(other.impl_))   {   }@@ -187,15 +199,16 @@    * constructed using the @c basic_resolver(const executor_type&) constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_resolver&-  > operator=(basic_resolver<InternetProtocol, Executor1>&& other)+  >::type operator=(basic_resolver<InternetProtocol, Executor1>&& other)   {     basic_resolver tmp(std::move(other));     impl_ = std::move(tmp.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destroys the resolver.   /**@@ -208,7 +221,7 @@   }    /// Get the executor associated with the object.-  executor_type get_executor() noexcept+  executor_type get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -224,8 +237,50 @@     return impl_.get_service().cancel(impl_.get_implementation());   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use overload with separate host and service parameters.)   /// Perform forward resolution of a query to a list of entries.   /**+   * This function is used to resolve a query into a list of endpoint entries.+   *+   * @param q A query object that determines what endpoints will be returned.+   *+   * @returns A range object representing the list of endpoint entries. A+   * successful call to this function is guaranteed to return a non-empty+   * range.+   *+   * @throws asio::system_error Thrown on failure.+   */+  results_type resolve(const query& q)+  {+    asio::error_code ec;+    results_type r = impl_.get_service().resolve(+        impl_.get_implementation(), q, ec);+    asio::detail::throw_error(ec, "resolve");+    return r;+  }++  /// (Deprecated: Use overload with separate host and service parameters.)+  /// Perform forward resolution of a query to a list of entries.+  /**+   * This function is used to resolve a query into a list of endpoint entries.+   *+   * @param q A query object that determines what endpoints will be returned.+   *+   * @param ec Set to indicate what error occurred, if any.+   *+   * @returns A range object representing the list of endpoint entries. An+   * empty range is returned if an error occurs. A successful call to this+   * function is guaranteed to return a non-empty range.+   */+  results_type resolve(const query& q, asio::error_code& ec)+  {+    return impl_.get_service().resolve(impl_.get_implementation(), q, ec);+  }+#endif // !defined(ASIO_NO_DEPRECATED)++  /// Perform forward resolution of a query to a list of entries.+  /**    * This function is used to resolve host and service names into a list of    * endpoint entries.    *@@ -590,8 +645,58 @@     return impl_.get_service().resolve(impl_.get_implementation(), q, ec);   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use overload with separate host and service parameters.)   /// Asynchronously perform forward resolution of a query to a list of entries.   /**+   * This function is used to asynchronously resolve a query into a list of+   * endpoint entries. It is an initiating function for an @ref+   * asynchronous_operation, and always returns immediately.+   *+   * @param q A query object that determines what endpoints will be returned.+   *+   * @param token The @ref completion_token that will be used to produce a+   * completion handler, which will be called when the resolve completes.+   * Potential completion tokens include @ref use_future, @ref use_awaitable,+   * @ref yield_context, or a function object with the correct completion+   * signature. The function signature of the completion handler must be:+   * @code void handler(+   *   const asio::error_code& error, // Result of operation.+   *   resolver::results_type results // Resolved endpoints as a range.+   * ); @endcode+   * Regardless of whether the asynchronous operation completes immediately or+   * not, the completion handler will not be invoked from within this function.+   * On immediate completion, invocation of the handler will be performed in a+   * manner equivalent to using asio::post().+   *+   * A successful resolve operation is guaranteed to pass a non-empty range to+   * the handler.+   *+   * @par Completion Signature+   * @code void(asio::error_code, results_type) @endcode+   */+  template <+      ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,+        results_type)) ResolveToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+      void (asio::error_code, results_type))+  async_resolve(const query& q,+      ASIO_MOVE_ARG(ResolveToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+      asio::async_initiate<ResolveToken,+        void (asio::error_code, results_type)>(+          declval<initiate_async_resolve>(), token, q)))+  {+    return asio::async_initiate<ResolveToken,+      void (asio::error_code, results_type)>(+        initiate_async_resolve(this), token, q);+  }+#endif // !defined(ASIO_NO_DEPRECATED)++  /// Asynchronously perform forward resolution of a query to a list of entries.+  /**    * This function is used to resolve host and service names into a list of    * endpoint entries.    *@@ -618,7 +723,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * A successful resolve operation is guaranteed to pass a non-empty range to    * the handler.@@ -639,18 +744,22 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        results_type)) ResolveToken = default_completion_token_t<executor_type>>-  auto async_resolve(ASIO_STRING_VIEW_PARAM host,+        results_type)) ResolveToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+      void (asio::error_code, results_type))+  async_resolve(ASIO_STRING_VIEW_PARAM host,       ASIO_STRING_VIEW_PARAM service,-      ResolveToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ResolveToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       asio::async_initiate<ResolveToken,         void (asio::error_code, results_type)>(           declval<initiate_async_resolve>(), token,-          declval<basic_resolver_query<protocol_type>&>()))+          declval<basic_resolver_query<protocol_type>&>())))   {     return async_resolve(host, service, resolver_base::flags(),-        static_cast<ResolveToken&&>(token));+        ASIO_MOVE_CAST(ResolveToken)(token));   }    /// Asynchronously perform forward resolution of a query to a list of entries.@@ -687,7 +796,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * A successful resolve operation is guaranteed to pass a non-empty range to    * the handler.@@ -708,15 +817,20 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        results_type)) ResolveToken = default_completion_token_t<executor_type>>-  auto async_resolve(ASIO_STRING_VIEW_PARAM host,-      ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags,-      ResolveToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        results_type)) ResolveToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+      void (asio::error_code, results_type))+  async_resolve(ASIO_STRING_VIEW_PARAM host,+      ASIO_STRING_VIEW_PARAM service,+      resolver_base::flags resolve_flags,+      ASIO_MOVE_ARG(ResolveToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       asio::async_initiate<ResolveToken,         void (asio::error_code, results_type)>(           declval<initiate_async_resolve>(), token,-          declval<basic_resolver_query<protocol_type>&>()))+          declval<basic_resolver_query<protocol_type>&>())))   {     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),         static_cast<std::string>(service), resolve_flags);@@ -758,7 +872,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * A successful resolve operation is guaranteed to pass a non-empty range to    * the handler.@@ -779,18 +893,22 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        results_type)) ResolveToken = default_completion_token_t<executor_type>>-  auto async_resolve(const protocol_type& protocol,+        results_type)) ResolveToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+      void (asio::error_code, results_type))+  async_resolve(const protocol_type& protocol,       ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service,-      ResolveToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ResolveToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       asio::async_initiate<ResolveToken,         void (asio::error_code, results_type)>(           declval<initiate_async_resolve>(), token,-          declval<basic_resolver_query<protocol_type>&>()))+          declval<basic_resolver_query<protocol_type>&>())))   {     return async_resolve(protocol, host, service, resolver_base::flags(),-        static_cast<ResolveToken&&>(token));+        ASIO_MOVE_CAST(ResolveToken)(token));   }    /// Asynchronously perform forward resolution of a query to a list of entries.@@ -830,7 +948,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * A successful resolve operation is guaranteed to pass a non-empty range to    * the handler.@@ -851,16 +969,20 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        results_type)) ResolveToken = default_completion_token_t<executor_type>>-  auto async_resolve(const protocol_type& protocol,+        results_type)) ResolveToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+      void (asio::error_code, results_type))+  async_resolve(const protocol_type& protocol,       ASIO_STRING_VIEW_PARAM host, ASIO_STRING_VIEW_PARAM service,       resolver_base::flags resolve_flags,-      ResolveToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+      ASIO_MOVE_ARG(ResolveToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       asio::async_initiate<ResolveToken,         void (asio::error_code, results_type)>(           declval<initiate_async_resolve>(), token,-          declval<basic_resolver_query<protocol_type>&>()))+          declval<basic_resolver_query<protocol_type>&>())))   {     basic_resolver_query<protocol_type> q(         protocol, static_cast<std::string>(host),@@ -935,7 +1057,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * A successful resolve operation is guaranteed to pass a non-empty range to    * the handler.@@ -945,13 +1067,17 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        results_type)) ResolveToken = default_completion_token_t<executor_type>>-  auto async_resolve(const endpoint_type& e,-      ResolveToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        results_type)) ResolveToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ResolveToken,+      void (asio::error_code, results_type))+  async_resolve(const endpoint_type& e,+      ASIO_MOVE_ARG(ResolveToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       asio::async_initiate<ResolveToken,         void (asio::error_code, results_type)>(-          declval<initiate_async_resolve>(), token, e))+          declval<initiate_async_resolve>(), token, e)))   {     return asio::async_initiate<ResolveToken,       void (asio::error_code, results_type)>(@@ -960,8 +1086,8 @@  private:   // Disallow copying and assignment.-  basic_resolver(const basic_resolver&) = delete;-  basic_resolver& operator=(const basic_resolver&) = delete;+  basic_resolver(const basic_resolver&) ASIO_DELETED;+  basic_resolver& operator=(const basic_resolver&) ASIO_DELETED;    class initiate_async_resolve   {@@ -973,13 +1099,13 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ResolveHandler, typename Query>-    void operator()(ResolveHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ResolveHandler) handler,         const Query& q) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_entry.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver_entry.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_iterator.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -79,13 +79,15 @@   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.   basic_resolver_iterator(basic_resolver_iterator&& other)-    : values_(static_cast<values_ptr_type&&>(other.values_)),+    : values_(ASIO_MOVE_CAST(values_ptr_type)(other.values_)),       index_(other.index_)   {     other.index_ = 0;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Assignment operator.   basic_resolver_iterator& operator=(const basic_resolver_iterator& other)@@ -95,18 +97,20 @@     return *this;   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-assignment operator.   basic_resolver_iterator& operator=(basic_resolver_iterator&& other)   {     if (this != &other)     {-      values_ = static_cast<values_ptr_type&&>(other.values_);+      values_ = ASIO_MOVE_CAST(values_ptr_type)(other.values_);       index_ = other.index_;       other.index_ = 0;     }      return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Dereference an iterator.   const basic_resolver_entry<InternetProtocol>& operator*() const@@ -174,7 +178,7 @@     return (*values_)[index_];   } -  typedef std::vector<basic_resolver_entry<InternetProtocol>> values_type;+  typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;   typedef asio::detail::shared_ptr<values_type> values_ptr_type;   values_ptr_type values_;   std::size_t index_;
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_query.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver_query.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -210,22 +210,6 @@     hints_.ai_canonname = 0;     hints_.ai_addr = 0;     hints_.ai_next = 0;-  }--  /// Copy construct a @c basic_resolver_query from another.-  basic_resolver_query(const basic_resolver_query& other)-    : hints_(other.hints_),-      host_name_(other.host_name_),-      service_name_(other.service_name_)-  {-  }--  /// Move construct a @c basic_resolver_query from another.-  basic_resolver_query(basic_resolver_query&& other)-    : hints_(other.hints_),-      host_name_(static_cast<std::string&&>(other.host_name_)),-      service_name_(static_cast<std::string&&>(other.service_name_))-  {   }    /// Get the hints associated with the query.
link/modules/asio-standalone/asio/include/asio/ip/basic_resolver_results.hpp view
@@ -2,7 +2,7 @@ // ip/basic_resolver_results.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -48,7 +48,11 @@  */ template <typename InternetProtocol> class basic_resolver_results+#if !defined(ASIO_NO_DEPRECATED)+  : public basic_resolver_iterator<InternetProtocol>+#else // !defined(ASIO_NO_DEPRECATED)   : private basic_resolver_iterator<InternetProtocol>+#endif // !defined(ASIO_NO_DEPRECATED) { public:   /// The protocol type associated with the results.@@ -89,12 +93,14 @@   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.   basic_resolver_results(basic_resolver_results&& other)     : basic_resolver_iterator<InternetProtocol>(-        static_cast<basic_resolver_results&&>(other))+        ASIO_MOVE_CAST(basic_resolver_results)(other))   {   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Assignment operator.   basic_resolver_results& operator=(const basic_resolver_results& other)@@ -103,13 +109,15 @@     return *this;   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-assignment operator.   basic_resolver_results& operator=(basic_resolver_results&& other)   {     basic_resolver_iterator<InternetProtocol>::operator=(-        static_cast<basic_resolver_results&&>(other));+        ASIO_MOVE_CAST(basic_resolver_results)(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  #if !defined(GENERATING_DOCUMENTATION)   // Create results from an addrinfo list returned by getaddrinfo.@@ -222,19 +230,19 @@ #endif // !defined(GENERATING_DOCUMENTATION)    /// Get the number of entries in the results range.-  size_type size() const noexcept+  size_type size() const ASIO_NOEXCEPT   {     return this->values_ ? this->values_->size() : 0;   }    /// Get the maximum number of entries permitted in a results range.-  size_type max_size() const noexcept+  size_type max_size() const ASIO_NOEXCEPT   {     return this->values_ ? this->values_->max_size() : values_type().max_size();   }    /// Determine whether the results range is empty.-  bool empty() const noexcept+  bool empty() const ASIO_NOEXCEPT   {     return this->values_ ? this->values_->empty() : true;   }@@ -244,7 +252,7 @@   {     basic_resolver_results tmp(*this);     tmp.index_ = 0;-    return static_cast<basic_resolver_results&&>(tmp);+    return ASIO_MOVE_CAST(basic_resolver_results)(tmp);   }    /// Obtain an end iterator for the results range.@@ -266,7 +274,7 @@   }    /// Swap the results range with another.-  void swap(basic_resolver_results& that) noexcept+  void swap(basic_resolver_results& that) ASIO_NOEXCEPT   {     if (this != &that)     {@@ -292,7 +300,7 @@   }  private:-  typedef std::vector<basic_resolver_entry<InternetProtocol>> values_type;+  typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type; };  } // namespace ip
link/modules/asio-standalone/asio/include/asio/ip/detail/endpoint.hpp view
@@ -2,7 +2,7 @@ // ip/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -28,48 +28,48 @@ namespace ip { namespace detail { -// Helper class for implementing an IP endpoint.+// Helper class for implementating an IP endpoint. class endpoint { public:   // Default constructor.-  ASIO_DECL endpoint() noexcept;+  ASIO_DECL endpoint() ASIO_NOEXCEPT;    // Construct an endpoint using a family and port number.   ASIO_DECL endpoint(int family,-      unsigned short port_num) noexcept;+      unsigned short port_num) ASIO_NOEXCEPT;    // Construct an endpoint using an address and port number.   ASIO_DECL endpoint(const asio::ip::address& addr,-      unsigned short port_num) noexcept;+      unsigned short port_num) ASIO_NOEXCEPT;    // Copy constructor.-  endpoint(const endpoint& other) noexcept+  endpoint(const endpoint& other) ASIO_NOEXCEPT     : data_(other.data_)   {   }    // Assign from another endpoint.-  endpoint& operator=(const endpoint& other) noexcept+  endpoint& operator=(const endpoint& other) ASIO_NOEXCEPT   {     data_ = other.data_;     return *this;   }    // Get the underlying endpoint in the native type.-  asio::detail::socket_addr_type* data() noexcept+  asio::detail::socket_addr_type* data() ASIO_NOEXCEPT   {-    return &data_.base[0];+    return &data_.base;   }    // Get the underlying endpoint in the native type.-  const asio::detail::socket_addr_type* data() const noexcept+  const asio::detail::socket_addr_type* data() const ASIO_NOEXCEPT   {-    return &data_.base[0];+    return &data_.base;   }    // Get the underlying size of the endpoint in the native type.-  std::size_t size() const noexcept+  std::size_t size() const ASIO_NOEXCEPT   {     if (is_v4())       return sizeof(asio::detail::sockaddr_in4_type);@@ -81,36 +81,36 @@   ASIO_DECL void resize(std::size_t new_size);    // Get the capacity of the endpoint in the native type.-  std::size_t capacity() const noexcept+  std::size_t capacity() const ASIO_NOEXCEPT   {     return sizeof(data_);   }    // Get the port associated with the endpoint.-  ASIO_DECL unsigned short port() const noexcept;+  ASIO_DECL unsigned short port() const ASIO_NOEXCEPT;    // Set the port associated with the endpoint.-  ASIO_DECL void port(unsigned short port_num) noexcept;+  ASIO_DECL void port(unsigned short port_num) ASIO_NOEXCEPT;    // Get the IP address associated with the endpoint.-  ASIO_DECL asio::ip::address address() const noexcept;+  ASIO_DECL asio::ip::address address() const ASIO_NOEXCEPT;    // Set the IP address associated with the endpoint.   ASIO_DECL void address(-      const asio::ip::address& addr) noexcept;+      const asio::ip::address& addr) ASIO_NOEXCEPT;    // Compare two endpoints for equality.   ASIO_DECL friend bool operator==(const endpoint& e1,-      const endpoint& e2) noexcept;+      const endpoint& e2) ASIO_NOEXCEPT;    // Compare endpoints for ordering.   ASIO_DECL friend bool operator<(const endpoint& e1,-      const endpoint& e2) noexcept;+      const endpoint& e2) ASIO_NOEXCEPT;    // Determine whether the endpoint is IPv4.-  bool is_v4() const noexcept+  bool is_v4() const ASIO_NOEXCEPT   {-    return data_.base[0].sa_family == ASIO_OS_DEF(AF_INET);+    return data_.base.sa_family == ASIO_OS_DEF(AF_INET);   }  #if !defined(ASIO_NO_IOSTREAM)@@ -122,11 +122,7 @@   // The underlying IP socket address.   union data_union   {-#if defined(_FORTIFY_SOURCE)-    asio::detail::socket_addr_type base[8];-#else // defined(_FORTIFY_SOURCE)-    asio::detail::socket_addr_type base[1];-#endif // defined(_FORTIFY_SOURCE)+    asio::detail::socket_addr_type base;     asio::detail::sockaddr_in4_type v4;     asio::detail::sockaddr_in6_type v6;   } data_;
link/modules/asio-standalone/asio/include/asio/ip/detail/impl/endpoint.ipp view
@@ -2,7 +2,7 @@ // ip/detail/impl/endpoint.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -31,7 +31,7 @@ namespace ip { namespace detail { -endpoint::endpoint() noexcept+endpoint::endpoint() ASIO_NOEXCEPT   : data_() {   data_.v4.sin_family = ASIO_OS_DEF(AF_INET);@@ -39,7 +39,7 @@   data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY); } -endpoint::endpoint(int family, unsigned short port_num) noexcept+endpoint::endpoint(int family, unsigned short port_num) ASIO_NOEXCEPT   : data_() {   using namespace std; // For memcpy.@@ -69,7 +69,7 @@ }  endpoint::endpoint(const asio::ip::address& addr,-    unsigned short port_num) noexcept+    unsigned short port_num) ASIO_NOEXCEPT   : data_() {   using namespace std; // For memcpy.@@ -106,7 +106,7 @@   } } -unsigned short endpoint::port() const noexcept+unsigned short endpoint::port() const ASIO_NOEXCEPT {   if (is_v4())   {@@ -120,7 +120,7 @@   } } -void endpoint::port(unsigned short port_num) noexcept+void endpoint::port(unsigned short port_num) ASIO_NOEXCEPT {   if (is_v4())   {@@ -134,7 +134,7 @@   } } -asio::ip::address endpoint::address() const noexcept+asio::ip::address endpoint::address() const ASIO_NOEXCEPT {   using namespace std; // For memcpy.   if (is_v4())@@ -146,23 +146,27 @@   else   {     asio::ip::address_v6::bytes_type bytes;+#if defined(ASIO_HAS_STD_ARRAY)     memcpy(bytes.data(), data_.v6.sin6_addr.s6_addr, 16);+#else // defined(ASIO_HAS_STD_ARRAY)+    memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16);+#endif // defined(ASIO_HAS_STD_ARRAY)     return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id);   } } -void endpoint::address(const asio::ip::address& addr) noexcept+void endpoint::address(const asio::ip::address& addr) ASIO_NOEXCEPT {   endpoint tmp_endpoint(addr, port());   data_ = tmp_endpoint.data_; } -bool operator==(const endpoint& e1, const endpoint& e2) noexcept+bool operator==(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT {   return e1.address() == e2.address() && e1.port() == e2.port(); } -bool operator<(const endpoint& e1, const endpoint& e2) noexcept+bool operator<(const endpoint& e1, const endpoint& e2) ASIO_NOEXCEPT {   if (e1.address() < e2.address())     return true;
link/modules/asio-standalone/asio/include/asio/ip/detail/socket_option.hpp view
@@ -2,7 +2,7 @@ // detail/socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -39,7 +39,7 @@ #if defined(__sun) || defined(__osf__)   typedef unsigned char ipv4_value_type;   typedef unsigned char ipv6_value_type;-#elif defined(_AIX) || defined(__hpux) || defined(__QNXNTO__)+#elif defined(_AIX) || defined(__hpux) || defined(__QNXNTO__)    typedef unsigned char ipv4_value_type;   typedef unsigned int ipv6_value_type; #else
link/modules/asio-standalone/asio/include/asio/ip/host_name.hpp view
@@ -2,7 +2,7 @@ // ip/host_name.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ip/icmp.hpp view
@@ -2,7 +2,7 @@ // ip/icmp.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -46,33 +46,33 @@   typedef basic_endpoint<icmp> endpoint;    /// Construct to represent the IPv4 ICMP protocol.-  static icmp v4() noexcept+  static icmp v4() ASIO_NOEXCEPT   {     return icmp(ASIO_OS_DEF(IPPROTO_ICMP),         ASIO_OS_DEF(AF_INET));   }    /// Construct to represent the IPv6 ICMP protocol.-  static icmp v6() noexcept+  static icmp v6() ASIO_NOEXCEPT   {     return icmp(ASIO_OS_DEF(IPPROTO_ICMPV6),         ASIO_OS_DEF(AF_INET6));   }    /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return ASIO_OS_DEF(SOCK_RAW);   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return protocol_;   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return family_;   }@@ -97,7 +97,7 @@  private:   // Construct with a specific family.-  explicit icmp(int protocol_id, int protocol_family) noexcept+  explicit icmp(int protocol_id, int protocol_family) ASIO_NOEXCEPT     : protocol_(protocol_id),       family_(protocol_family)   {
link/modules/asio-standalone/asio/include/asio/ip/impl/address.hpp view
@@ -2,7 +2,7 @@ // ip/impl/address.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,10 +17,38 @@  #if !defined(ASIO_NO_IOSTREAM) +#include "asio/detail/throw_error.hpp"+ #include "asio/detail/push_options.hpp"  namespace asio { namespace ip {++#if !defined(ASIO_NO_DEPRECATED)++inline address address::from_string(const char* str)+{+  return asio::ip::make_address(str);+}++inline address address::from_string(+    const char* str, asio::error_code& ec)+{+  return asio::ip::make_address(str, ec);+}++inline address address::from_string(const std::string& str)+{+  return asio::ip::make_address(str);+}++inline address address::from_string(+    const std::string& str, asio::error_code& ec)+{+  return asio::ip::make_address(str, ec);+}++#endif // !defined(ASIO_NO_DEPRECATED)  template <typename Elem, typename Traits> std::basic_ostream<Elem, Traits>& operator<<(
link/modules/asio-standalone/asio/include/asio/ip/impl/address.ipp view
@@ -2,7 +2,7 @@ // ip/impl/address.ipp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -29,7 +29,7 @@ namespace asio { namespace ip { -address::address() noexcept+address::address() ASIO_NOEXCEPT   : type_(ipv4),     ipv4_address_(),     ipv6_address_()@@ -37,7 +37,7 @@ }  address::address(-    const asio::ip::address_v4& ipv4_address) noexcept+    const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT   : type_(ipv4),     ipv4_address_(ipv4_address),     ipv6_address_()@@ -45,28 +45,30 @@ }  address::address(-    const asio::ip::address_v6& ipv6_address) noexcept+    const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT   : type_(ipv6),     ipv4_address_(),     ipv6_address_(ipv6_address) { } -address::address(const address& other) noexcept+address::address(const address& other) ASIO_NOEXCEPT   : type_(other.type_),     ipv4_address_(other.ipv4_address_),     ipv6_address_(other.ipv6_address_) { } -address::address(address&& other) noexcept+#if defined(ASIO_HAS_MOVE)+address::address(address&& other) ASIO_NOEXCEPT   : type_(other.type_),     ipv4_address_(other.ipv4_address_),     ipv6_address_(other.ipv6_address_) { }+#endif // defined(ASIO_HAS_MOVE) -address& address::operator=(const address& other) noexcept+address& address::operator=(const address& other) ASIO_NOEXCEPT {   type_ = other.type_;   ipv4_address_ = other.ipv4_address_;@@ -74,16 +76,18 @@   return *this; } -address& address::operator=(address&& other) noexcept+#if defined(ASIO_HAS_MOVE)+address& address::operator=(address&& other) ASIO_NOEXCEPT {   type_ = other.type_;   ipv4_address_ = other.ipv4_address_;   ipv6_address_ = other.ipv6_address_;   return *this; }+#endif // defined(ASIO_HAS_MOVE)  address& address::operator=(-    const asio::ip::address_v4& ipv4_address) noexcept+    const asio::ip::address_v4& ipv4_address) ASIO_NOEXCEPT {   type_ = ipv4;   ipv4_address_ = ipv4_address;@@ -92,7 +96,7 @@ }  address& address::operator=(-    const asio::ip::address_v6& ipv6_address) noexcept+    const asio::ip::address_v6& ipv6_address) ASIO_NOEXCEPT {   type_ = ipv6;   ipv4_address_ = asio::ip::address_v4();@@ -109,7 +113,7 @@ }  address make_address(const char* str,-    asio::error_code& ec) noexcept+    asio::error_code& ec) ASIO_NOEXCEPT {   asio::ip::address_v6 ipv6_address =     asio::ip::make_address_v6(str, ec);@@ -130,7 +134,7 @@ }  address make_address(const std::string& str,-    asio::error_code& ec) noexcept+    asio::error_code& ec) ASIO_NOEXCEPT {   return make_address(str.c_str(), ec); }@@ -143,7 +147,7 @@ }  address make_address(string_view str,-    asio::error_code& ec) noexcept+    asio::error_code& ec) ASIO_NOEXCEPT {   return make_address(static_cast<std::string>(str), ec); }@@ -177,28 +181,37 @@   return ipv4_address_.to_string(); } -bool address::is_loopback() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+std::string address::to_string(asio::error_code& ec) const {+  if (type_ == ipv6)+    return ipv6_address_.to_string(ec);+  return ipv4_address_.to_string(ec);+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address::is_loopback() const ASIO_NOEXCEPT+{   return (type_ == ipv4)     ? ipv4_address_.is_loopback()     : ipv6_address_.is_loopback(); } -bool address::is_unspecified() const noexcept+bool address::is_unspecified() const ASIO_NOEXCEPT {   return (type_ == ipv4)     ? ipv4_address_.is_unspecified()     : ipv6_address_.is_unspecified(); } -bool address::is_multicast() const noexcept+bool address::is_multicast() const ASIO_NOEXCEPT {   return (type_ == ipv4)     ? ipv4_address_.is_multicast()     : ipv6_address_.is_multicast(); } -bool operator==(const address& a1, const address& a2) noexcept+bool operator==(const address& a1, const address& a2) ASIO_NOEXCEPT {   if (a1.type_ != a2.type_)     return false;@@ -207,7 +220,7 @@   return a1.ipv4_address_ == a2.ipv4_address_; } -bool operator<(const address& a1, const address& a2) noexcept+bool operator<(const address& a1, const address& a2) ASIO_NOEXCEPT {   if (a1.type_ < a2.type_)     return true;
link/modules/asio-standalone/asio/include/asio/ip/impl/address_v4.hpp view
@@ -2,7 +2,7 @@ // ip/impl/address_v4.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,10 +17,38 @@  #if !defined(ASIO_NO_IOSTREAM) +#include "asio/detail/throw_error.hpp"+ #include "asio/detail/push_options.hpp"  namespace asio { namespace ip {++#if !defined(ASIO_NO_DEPRECATED)++inline address_v4 address_v4::from_string(const char* str)+{+  return asio::ip::make_address_v4(str);+}++inline address_v4 address_v4::from_string(+    const char* str, asio::error_code& ec)+{+  return asio::ip::make_address_v4(str, ec);+}++inline address_v4 address_v4::from_string(const std::string& str)+{+  return asio::ip::make_address_v4(str);+}++inline address_v4 address_v4::from_string(+    const std::string& str, asio::error_code& ec)+{+  return asio::ip::make_address_v4(str, ec);+}++#endif // !defined(ASIO_NO_DEPRECATED)  template <typename Elem, typename Traits> std::basic_ostream<Elem, Traits>& operator<<(
link/modules/asio-standalone/asio/include/asio/ip/impl/address_v4.ipp view
@@ -2,7 +2,7 @@ // ip/impl/address_v4.ipp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -57,19 +57,30 @@       static_cast<asio::detail::u_long_type>(addr)); } -address_v4::bytes_type address_v4::to_bytes() const noexcept+address_v4::bytes_type address_v4::to_bytes() const ASIO_NOEXCEPT {   using namespace std; // For memcpy.   bytes_type bytes;+#if defined(ASIO_HAS_STD_ARRAY)   memcpy(bytes.data(), &addr_.s_addr, 4);+#else // defined(ASIO_HAS_STD_ARRAY)+  memcpy(bytes.elems, &addr_.s_addr, 4);+#endif // defined(ASIO_HAS_STD_ARRAY)   return bytes; } -address_v4::uint_type address_v4::to_uint() const noexcept+address_v4::uint_type address_v4::to_uint() const ASIO_NOEXCEPT {   return asio::detail::socket_ops::network_to_host_long(addr_.s_addr); } +#if !defined(ASIO_NO_DEPRECATED)+unsigned long address_v4::to_ulong() const+{+  return asio::detail::socket_ops::network_to_host_long(addr_.s_addr);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ std::string address_v4::to_string() const {   asio::error_code ec;@@ -83,21 +94,70 @@   return addr; } -bool address_v4::is_loopback() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+std::string address_v4::to_string(asio::error_code& ec) const {+  char addr_str[asio::detail::max_addr_v4_str_len];+  const char* addr =+    asio::detail::socket_ops::inet_ntop(+        ASIO_OS_DEF(AF_INET), &addr_, addr_str,+        asio::detail::max_addr_v4_str_len, 0, ec);+  if (addr == 0)+    return std::string();+  return addr;+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address_v4::is_loopback() const ASIO_NOEXCEPT+{   return (to_uint() & 0xFF000000) == 0x7F000000; } -bool address_v4::is_unspecified() const noexcept+bool address_v4::is_unspecified() const ASIO_NOEXCEPT {   return to_uint() == 0; } -bool address_v4::is_multicast() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+bool address_v4::is_class_a() const {+  return (to_uint() & 0x80000000) == 0;+}++bool address_v4::is_class_b() const+{+  return (to_uint() & 0xC0000000) == 0x80000000;+}++bool address_v4::is_class_c() const+{+  return (to_uint() & 0xE0000000) == 0xC0000000;+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address_v4::is_multicast() const ASIO_NOEXCEPT+{   return (to_uint() & 0xF0000000) == 0xE0000000; } +#if !defined(ASIO_NO_DEPRECATED)+address_v4 address_v4::broadcast(const address_v4& addr, const address_v4& mask)+{+  return address_v4(addr.to_uint() | (mask.to_uint() ^ 0xFFFFFFFF));+}++address_v4 address_v4::netmask(const address_v4& addr)+{+  if (addr.is_class_a())+    return address_v4(0xFF000000);+  if (addr.is_class_b())+    return address_v4(0xFFFF0000);+  if (addr.is_class_c())+    return address_v4(0xFFFFFF00);+  return address_v4(0xFFFFFFFF);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ address_v4 make_address_v4(const char* str) {   asio::error_code ec;@@ -107,7 +167,7 @@ }  address_v4 make_address_v4(const char* str,-    asio::error_code& ec) noexcept+    asio::error_code& ec) ASIO_NOEXCEPT {   address_v4::bytes_type bytes;   if (asio::detail::socket_ops::inet_pton(@@ -122,7 +182,7 @@ }  address_v4 make_address_v4(const std::string& str,-    asio::error_code& ec) noexcept+    asio::error_code& ec) ASIO_NOEXCEPT {   return make_address_v4(str.c_str(), ec); }@@ -135,7 +195,7 @@ }  address_v4 make_address_v4(string_view str,-    asio::error_code& ec) noexcept+    asio::error_code& ec) ASIO_NOEXCEPT {   return make_address_v4(static_cast<std::string>(str), ec); }
link/modules/asio-standalone/asio/include/asio/ip/impl/address_v6.hpp view
@@ -2,7 +2,7 @@ // ip/impl/address_v6.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,10 +17,38 @@  #if !defined(ASIO_NO_IOSTREAM) +#include "asio/detail/throw_error.hpp"+ #include "asio/detail/push_options.hpp"  namespace asio { namespace ip {++#if !defined(ASIO_NO_DEPRECATED)++inline address_v6 address_v6::from_string(const char* str)+{+  return asio::ip::make_address_v6(str);+}++inline address_v6 address_v6::from_string(+    const char* str, asio::error_code& ec)+{+  return asio::ip::make_address_v6(str, ec);+}++inline address_v6 address_v6::from_string(const std::string& str)+{+  return asio::ip::make_address_v6(str);+}++inline address_v6 address_v6::from_string(+    const std::string& str, asio::error_code& ec)+{+  return asio::ip::make_address_v6(str, ec);+}++#endif // !defined(ASIO_NO_DEPRECATED)  template <typename Elem, typename Traits> std::basic_ostream<Elem, Traits>& operator<<(
link/modules/asio-standalone/asio/include/asio/ip/impl/address_v6.ipp view
@@ -2,7 +2,7 @@ // ip/impl/address_v6.ipp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -31,7 +31,7 @@ namespace asio { namespace ip { -address_v6::address_v6() noexcept+address_v6::address_v6() ASIO_NOEXCEPT   : addr_(),     scope_id_(0) {@@ -56,37 +56,45 @@   memcpy(addr_.s6_addr, bytes.data(), 16); } -address_v6::address_v6(const address_v6& other) noexcept+address_v6::address_v6(const address_v6& other) ASIO_NOEXCEPT   : addr_(other.addr_),     scope_id_(other.scope_id_) { } -address_v6::address_v6(address_v6&& other) noexcept+#if defined(ASIO_HAS_MOVE)+address_v6::address_v6(address_v6&& other) ASIO_NOEXCEPT   : addr_(other.addr_),     scope_id_(other.scope_id_) { }+#endif // defined(ASIO_HAS_MOVE) -address_v6& address_v6::operator=(const address_v6& other) noexcept+address_v6& address_v6::operator=(const address_v6& other) ASIO_NOEXCEPT {   addr_ = other.addr_;   scope_id_ = other.scope_id_;   return *this; } -address_v6& address_v6::operator=(address_v6&& other) noexcept+#if defined(ASIO_HAS_MOVE)+address_v6& address_v6::operator=(address_v6&& other) ASIO_NOEXCEPT {   addr_ = other.addr_;   scope_id_ = other.scope_id_;   return *this; }+#endif // defined(ASIO_HAS_MOVE) -address_v6::bytes_type address_v6::to_bytes() const noexcept+address_v6::bytes_type address_v6::to_bytes() const ASIO_NOEXCEPT {   using namespace std; // For memcpy.   bytes_type bytes;+#if defined(ASIO_HAS_STD_ARRAY)   memcpy(bytes.data(), addr_.s6_addr, 16);+#else // defined(ASIO_HAS_STD_ARRAY)+  memcpy(bytes.elems, addr_.s6_addr, 16);+#endif // defined(ASIO_HAS_STD_ARRAY)   return bytes; } @@ -103,8 +111,35 @@   return addr; } -bool address_v6::is_loopback() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+std::string address_v6::to_string(asio::error_code& ec) const {+  char addr_str[asio::detail::max_addr_v6_str_len];+  const char* addr =+    asio::detail::socket_ops::inet_ntop(+        ASIO_OS_DEF(AF_INET6), &addr_, addr_str,+        asio::detail::max_addr_v6_str_len, scope_id_, ec);+  if (addr == 0)+    return std::string();+  return addr;+}++address_v4 address_v6::to_v4() const+{+  if (!is_v4_mapped() && !is_v4_compatible())+  {+    bad_address_cast ex;+    asio::detail::throw_exception(ex);+  }++  address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12],+    addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } };+  return address_v4(v4_bytes);+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address_v6::is_loopback() const ASIO_NOEXCEPT+{   return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)       && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)       && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)@@ -115,7 +150,7 @@       && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1)); } -bool address_v6::is_unspecified() const noexcept+bool address_v6::is_unspecified() const ASIO_NOEXCEPT {   return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)       && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)@@ -127,17 +162,17 @@       && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0)); } -bool address_v6::is_link_local() const noexcept+bool address_v6::is_link_local() const ASIO_NOEXCEPT {   return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0x80)); } -bool address_v6::is_site_local() const noexcept+bool address_v6::is_site_local() const ASIO_NOEXCEPT {   return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0xc0)); } -bool address_v6::is_v4_mapped() const noexcept+bool address_v6::is_v4_mapped() const ASIO_NOEXCEPT {   return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)       && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)@@ -147,37 +182,53 @@       && (addr_.s6_addr[10] == 0xff) && (addr_.s6_addr[11] == 0xff)); } -bool address_v6::is_multicast() const noexcept+#if !defined(ASIO_NO_DEPRECATED)+bool address_v6::is_v4_compatible() const {+  return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)+      && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)+      && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)+      && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)+      && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)+      && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)+      && !((addr_.s6_addr[12] == 0)+        && (addr_.s6_addr[13] == 0)+        && (addr_.s6_addr[14] == 0)+        && ((addr_.s6_addr[15] == 0) || (addr_.s6_addr[15] == 1))));+}+#endif // !defined(ASIO_NO_DEPRECATED)++bool address_v6::is_multicast() const ASIO_NOEXCEPT+{   return (addr_.s6_addr[0] == 0xff); } -bool address_v6::is_multicast_global() const noexcept+bool address_v6::is_multicast_global() const ASIO_NOEXCEPT {   return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x0e)); } -bool address_v6::is_multicast_link_local() const noexcept+bool address_v6::is_multicast_link_local() const ASIO_NOEXCEPT {   return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x02)); } -bool address_v6::is_multicast_node_local() const noexcept+bool address_v6::is_multicast_node_local() const ASIO_NOEXCEPT {   return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x01)); } -bool address_v6::is_multicast_org_local() const noexcept+bool address_v6::is_multicast_org_local() const ASIO_NOEXCEPT {   return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x08)); } -bool address_v6::is_multicast_site_local() const noexcept+bool address_v6::is_multicast_site_local() const ASIO_NOEXCEPT {   return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x05)); } -bool operator==(const address_v6& a1, const address_v6& a2) noexcept+bool operator==(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT {   using namespace std; // For memcmp.   return memcmp(&a1.addr_, &a2.addr_,@@ -185,7 +236,7 @@     && a1.scope_id_ == a2.scope_id_; } -bool operator<(const address_v6& a1, const address_v6& a2) noexcept+bool operator<(const address_v6& a1, const address_v6& a2) ASIO_NOEXCEPT {   using namespace std; // For memcmp.   int memcmp_result = memcmp(&a1.addr_, &a2.addr_,@@ -197,13 +248,31 @@   return a1.scope_id_ < a2.scope_id_; } -address_v6 address_v6::loopback() noexcept+address_v6 address_v6::loopback() ASIO_NOEXCEPT {   address_v6 tmp;   tmp.addr_.s6_addr[15] = 1;   return tmp; } +#if !defined(ASIO_NO_DEPRECATED)+address_v6 address_v6::v4_mapped(const address_v4& addr)+{+  address_v4::bytes_type v4_bytes = addr.to_bytes();+  bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF,+    v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };+  return address_v6(v6_bytes);+}++address_v6 address_v6::v4_compatible(const address_v4& addr)+{+  address_v4::bytes_type v4_bytes = addr.to_bytes();+  bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+    v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };+  return address_v6(v6_bytes);+}+#endif // !defined(ASIO_NO_DEPRECATED)+ address_v6 make_address_v6(const char* str) {   asio::error_code ec;@@ -213,14 +282,14 @@ }  address_v6 make_address_v6(const char* str,-    asio::error_code& ec) noexcept+    asio::error_code& ec) ASIO_NOEXCEPT {   address_v6::bytes_type bytes;   unsigned long scope_id = 0;   if (asio::detail::socket_ops::inet_pton(         ASIO_OS_DEF(AF_INET6), str, &bytes[0], &scope_id, ec) <= 0)     return address_v6();-  return address_v6(bytes, static_cast<scope_id_type>(scope_id));+  return address_v6(bytes, scope_id); }  address_v6 make_address_v6(const std::string& str)@@ -229,7 +298,7 @@ }  address_v6 make_address_v6(const std::string& str,-    asio::error_code& ec) noexcept+    asio::error_code& ec) ASIO_NOEXCEPT {   return make_address_v6(str.c_str(), ec); }@@ -242,7 +311,7 @@ }  address_v6 make_address_v6(string_view str,-    asio::error_code& ec) noexcept+    asio::error_code& ec) ASIO_NOEXCEPT {   return make_address_v6(static_cast<std::string>(str), ec); }
link/modules/asio-standalone/asio/include/asio/ip/impl/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // ip/impl/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ip/impl/host_name.ipp view
@@ -2,7 +2,7 @@ // ip/impl/host_name.ipp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ip/impl/network_v4.hpp view
@@ -2,7 +2,7 @@ // ip/impl/network_v4.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/ip/impl/network_v4.ipp view
@@ -2,7 +2,7 @@ // ip/impl/network_v4.ipp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -91,7 +91,7 @@   } } -address_v4 network_v4::netmask() const noexcept+address_v4 network_v4::netmask() const ASIO_NOEXCEPT {   uint32_t nmbits = 0xffffffff;   if (prefix_length_ == 0)@@ -101,7 +101,7 @@   return address_v4(nmbits); } -address_v4_range network_v4::hosts() const noexcept+address_v4_range network_v4::hosts() const ASIO_NOEXCEPT {   return is_host()     ? address_v4_range(address_, address_v4(address_.to_uint() + 1))
link/modules/asio-standalone/asio/include/asio/ip/impl/network_v6.hpp view
@@ -2,7 +2,7 @@ // ip/impl/network_v6.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ip/impl/network_v6.ipp view
@@ -2,7 +2,7 @@ // ip/impl/network_v6.ipp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -42,7 +42,7 @@   } } -ASIO_DECL address_v6 network_v6::network() const noexcept+ASIO_DECL address_v6 network_v6::network() const ASIO_NOEXCEPT {   address_v6::bytes_type bytes(address_.to_bytes());   for (std::size_t i = 0; i < 16; ++i)@@ -55,7 +55,7 @@   return address_v6(bytes, address_.scope_id()); } -address_v6_range network_v6::hosts() const noexcept+address_v6_range network_v6::hosts() const ASIO_NOEXCEPT {   address_v6::bytes_type begin_bytes(address_.to_bytes());   address_v6::bytes_type end_bytes(address_.to_bytes());
link/modules/asio-standalone/asio/include/asio/ip/multicast.hpp view
@@ -2,7 +2,7 @@ // ip/multicast.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ip/network_v4.hpp view
@@ -2,7 +2,7 @@ // ip/network_v4.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -40,7 +40,7 @@ { public:   /// Default constructor.-  network_v4() noexcept+  network_v4() ASIO_NOEXCEPT     : address_(),       prefix_length_(0)   {@@ -55,74 +55,78 @@       const address_v4& mask);    /// Copy constructor.-  network_v4(const network_v4& other) noexcept+  network_v4(const network_v4& other) ASIO_NOEXCEPT     : address_(other.address_),       prefix_length_(other.prefix_length_)   {   } +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  network_v4(network_v4&& other) noexcept-    : address_(static_cast<address_v4&&>(other.address_)),+  network_v4(network_v4&& other) ASIO_NOEXCEPT+    : address_(ASIO_MOVE_CAST(address_v4)(other.address_)),       prefix_length_(other.prefix_length_)   {   }+#endif // defined(ASIO_HAS_MOVE)    /// Assign from another network.-  network_v4& operator=(const network_v4& other) noexcept+  network_v4& operator=(const network_v4& other) ASIO_NOEXCEPT   {     address_ = other.address_;     prefix_length_ = other.prefix_length_;     return *this;   } +#if defined(ASIO_HAS_MOVE)   /// Move-assign from another network.-  network_v4& operator=(network_v4&& other) noexcept+  network_v4& operator=(network_v4&& other) ASIO_NOEXCEPT   {-    address_ = static_cast<address_v4&&>(other.address_);+    address_ = ASIO_MOVE_CAST(address_v4)(other.address_);     prefix_length_ = other.prefix_length_;     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    /// Obtain the address object specified when the network object was created.-  address_v4 address() const noexcept+  address_v4 address() const ASIO_NOEXCEPT   {     return address_;   }    /// Obtain the prefix length that was specified when the network object was   /// created.-  unsigned short prefix_length() const noexcept+  unsigned short prefix_length() const ASIO_NOEXCEPT   {     return prefix_length_;   }    /// Obtain the netmask that was specified when the network object was created.-  ASIO_DECL address_v4 netmask() const noexcept;+  ASIO_DECL address_v4 netmask() const ASIO_NOEXCEPT;    /// Obtain an address object that represents the network address.-  address_v4 network() const noexcept+  address_v4 network() const ASIO_NOEXCEPT   {     return address_v4(address_.to_uint() & netmask().to_uint());   }    /// Obtain an address object that represents the network's broadcast address.-  address_v4 broadcast() const noexcept+  address_v4 broadcast() const ASIO_NOEXCEPT   {     return address_v4(network().to_uint() | (netmask().to_uint() ^ 0xFFFFFFFF));   }    /// Obtain an address range corresponding to the hosts in the network.-  ASIO_DECL address_v4_range hosts() const noexcept;+  ASIO_DECL address_v4_range hosts() const ASIO_NOEXCEPT;    /// Obtain the true network address, omitting any host bits.-  network_v4 canonical() const noexcept+  network_v4 canonical() const ASIO_NOEXCEPT   {     return network_v4(network(), prefix_length());   }    /// Test if network is a valid host address.-  bool is_host() const noexcept+  bool is_host() const ASIO_NOEXCEPT   {     return prefix_length_ == 32;   }
link/modules/asio-standalone/asio/include/asio/ip/network_v6.hpp view
@@ -2,7 +2,7 @@ // ip/network_v6.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -40,7 +40,7 @@ { public:   /// Default constructor.-  network_v6() noexcept+  network_v6() ASIO_NOEXCEPT     : address_(),       prefix_length_(0)   {@@ -51,62 +51,66 @@       unsigned short prefix_len);    /// Copy constructor.-  network_v6(const network_v6& other) noexcept+  network_v6(const network_v6& other) ASIO_NOEXCEPT     : address_(other.address_),       prefix_length_(other.prefix_length_)   {   } +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  network_v6(network_v6&& other) noexcept-    : address_(static_cast<address_v6&&>(other.address_)),+  network_v6(network_v6&& other) ASIO_NOEXCEPT+    : address_(ASIO_MOVE_CAST(address_v6)(other.address_)),       prefix_length_(other.prefix_length_)   {   }+#endif // defined(ASIO_HAS_MOVE)    /// Assign from another network.-  network_v6& operator=(const network_v6& other) noexcept+  network_v6& operator=(const network_v6& other) ASIO_NOEXCEPT   {     address_ = other.address_;     prefix_length_ = other.prefix_length_;     return *this;   } +#if defined(ASIO_HAS_MOVE)   /// Move-assign from another network.-  network_v6& operator=(network_v6&& other) noexcept+  network_v6& operator=(network_v6&& other) ASIO_NOEXCEPT   {-    address_ = static_cast<address_v6&&>(other.address_);+    address_ = ASIO_MOVE_CAST(address_v6)(other.address_);     prefix_length_ = other.prefix_length_;     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    /// Obtain the address object specified when the network object was created.-  address_v6 address() const noexcept+  address_v6 address() const ASIO_NOEXCEPT   {     return address_;   }    /// Obtain the prefix length that was specified when the network object was   /// created.-  unsigned short prefix_length() const noexcept+  unsigned short prefix_length() const ASIO_NOEXCEPT   {     return prefix_length_;   }    /// Obtain an address object that represents the network address.-  ASIO_DECL address_v6 network() const noexcept;+  ASIO_DECL address_v6 network() const ASIO_NOEXCEPT;    /// Obtain an address range corresponding to the hosts in the network.-  ASIO_DECL address_v6_range hosts() const noexcept;+  ASIO_DECL address_v6_range hosts() const ASIO_NOEXCEPT;    /// Obtain the true network address, omitting any host bits.-  network_v6 canonical() const noexcept+  network_v6 canonical() const ASIO_NOEXCEPT   {     return network_v6(network(), prefix_length());   }    /// Test if network is a valid host address.-  bool is_host() const noexcept+  bool is_host() const ASIO_NOEXCEPT   {     return prefix_length_ == 128;   }
link/modules/asio-standalone/asio/include/asio/ip/resolver_base.hpp view
@@ -2,7 +2,7 @@ // ip/resolver_base.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ip/resolver_query_base.hpp view
@@ -2,7 +2,7 @@ // ip/resolver_query_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ip/tcp.hpp view
@@ -2,7 +2,7 @@ // ip/tcp.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -49,31 +49,31 @@   typedef basic_endpoint<tcp> endpoint;    /// Construct to represent the IPv4 TCP protocol.-  static tcp v4() noexcept+  static tcp v4() ASIO_NOEXCEPT   {     return tcp(ASIO_OS_DEF(AF_INET));   }    /// Construct to represent the IPv6 TCP protocol.-  static tcp v6() noexcept+  static tcp v6() ASIO_NOEXCEPT   {     return tcp(ASIO_OS_DEF(AF_INET6));   }    /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return ASIO_OS_DEF(SOCK_STREAM);   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return ASIO_OS_DEF(IPPROTO_TCP);   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return family_;   }@@ -139,7 +139,7 @@  private:   // Construct with a specific family.-  explicit tcp(int protocol_family) noexcept+  explicit tcp(int protocol_family) ASIO_NOEXCEPT     : family_(protocol_family)   {   }
link/modules/asio-standalone/asio/include/asio/ip/udp.hpp view
@@ -2,7 +2,7 @@ // ip/udp.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -46,31 +46,31 @@   typedef basic_endpoint<udp> endpoint;    /// Construct to represent the IPv4 UDP protocol.-  static udp v4() noexcept+  static udp v4() ASIO_NOEXCEPT   {     return udp(ASIO_OS_DEF(AF_INET));   }    /// Construct to represent the IPv6 UDP protocol.-  static udp v6() noexcept+  static udp v6() ASIO_NOEXCEPT   {     return udp(ASIO_OS_DEF(AF_INET6));   }    /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return ASIO_OS_DEF(SOCK_DGRAM);   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return ASIO_OS_DEF(IPPROTO_UDP);   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return family_;   }@@ -95,7 +95,7 @@  private:   // Construct with a specific family.-  explicit udp(int protocol_family) noexcept+  explicit udp(int protocol_family) ASIO_NOEXCEPT     : family_(protocol_family)   {   }
link/modules/asio-standalone/asio/include/asio/ip/unicast.hpp view
@@ -2,7 +2,7 @@ // ip/unicast.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ip/v6_only.hpp view
@@ -2,7 +2,7 @@ // ip/v6_only.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/is_applicable_property.hpp view
@@ -2,7 +2,7 @@ // is_applicable_property.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -30,11 +30,11 @@  template <typename T, typename Property> struct is_applicable_property_trait<T, Property,-  void_t<-    enable_if_t<+  typename void_type<+    typename enable_if<       !!Property::template is_applicable_property_v<T>-    >-  >> : true_type+    >::type+  >::type> : true_type { }; @@ -51,7 +51,7 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES)  template <typename T, typename Property>-constexpr const bool is_applicable_property_v+ASIO_CONSTEXPR const bool is_applicable_property_v   = is_applicable_property<T, Property>::value;  #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)
link/modules/asio-standalone/asio/include/asio/is_contiguous_iterator.hpp view
@@ -2,7 +2,7 @@ // is_contiguous_iterator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -29,7 +29,7 @@ struct is_contiguous_iterator : #if defined(ASIO_HAS_STD_CONCEPTS) \   || defined(GENERATING_DOCUMENTATION)-  integral_constant<bool, std::contiguous_iterator<T>>+  integral_constant<bool, std::contiguous_iterator<T> > #else // defined(ASIO_HAS_STD_CONCEPTS)       //   || defined(GENERATING_DOCUMENTATION)   is_pointer<T>
link/modules/asio-standalone/asio/include/asio/is_executor.hpp view
@@ -2,7 +2,7 @@ // is_executor.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/is_read_buffered.hpp view
@@ -2,7 +2,7 @@ // is_read_buffered.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/is_write_buffered.hpp view
@@ -2,7 +2,7 @@ // is_write_buffered.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/local/basic_endpoint.hpp view
@@ -2,7 +2,7 @@ // local/basic_endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -60,7 +60,7 @@ #endif    /// Default constructor.-  basic_endpoint() noexcept+  basic_endpoint() ASIO_NOEXCEPT   {   } @@ -85,51 +85,55 @@   #endif // defined(ASIO_HAS_STRING_VIEW)    /// Copy constructor.-  basic_endpoint(const basic_endpoint& other) noexcept+  basic_endpoint(const basic_endpoint& other)     : impl_(other.impl_)   {   } +#if defined(ASIO_HAS_MOVE)   /// Move constructor.-  basic_endpoint(basic_endpoint&& other) noexcept+  basic_endpoint(basic_endpoint&& other)     : impl_(other.impl_)   {   }+#endif // defined(ASIO_HAS_MOVE)    /// Assign from another endpoint.-  basic_endpoint& operator=(const basic_endpoint& other) noexcept+  basic_endpoint& operator=(const basic_endpoint& other)   {     impl_ = other.impl_;     return *this;   } +#if defined(ASIO_HAS_MOVE)   /// Move-assign from another endpoint.-  basic_endpoint& operator=(basic_endpoint&& other) noexcept+  basic_endpoint& operator=(basic_endpoint&& other)   {     impl_ = other.impl_;     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    /// The protocol associated with the endpoint.-  protocol_type protocol() const noexcept+  protocol_type protocol() const   {     return protocol_type();   }    /// Get the underlying endpoint in the native type.-  data_type* data() noexcept+  data_type* data()   {     return impl_.data();   }    /// Get the underlying endpoint in the native type.-  const data_type* data() const noexcept+  const data_type* data() const   {     return impl_.data();   }    /// Get the underlying size of the endpoint in the native type.-  std::size_t size() const noexcept+  std::size_t size() const   {     return impl_.size();   }@@ -141,7 +145,7 @@   }    /// Get the capacity of the endpoint in the native type.-  std::size_t capacity() const noexcept+  std::size_t capacity() const   {     return impl_.capacity();   }@@ -166,42 +170,42 @@    /// Compare two endpoints for equality.   friend bool operator==(const basic_endpoint<Protocol>& e1,-      const basic_endpoint<Protocol>& e2) noexcept+      const basic_endpoint<Protocol>& e2)   {     return e1.impl_ == e2.impl_;   }    /// Compare two endpoints for inequality.   friend bool operator!=(const basic_endpoint<Protocol>& e1,-      const basic_endpoint<Protocol>& e2) noexcept+      const basic_endpoint<Protocol>& e2)   {     return !(e1.impl_ == e2.impl_);   }    /// Compare endpoints for ordering.   friend bool operator<(const basic_endpoint<Protocol>& e1,-      const basic_endpoint<Protocol>& e2) noexcept+      const basic_endpoint<Protocol>& e2)   {     return e1.impl_ < e2.impl_;   }    /// Compare endpoints for ordering.   friend bool operator>(const basic_endpoint<Protocol>& e1,-      const basic_endpoint<Protocol>& e2) noexcept+      const basic_endpoint<Protocol>& e2)   {     return e2.impl_ < e1.impl_;   }    /// Compare endpoints for ordering.   friend bool operator<=(const basic_endpoint<Protocol>& e1,-      const basic_endpoint<Protocol>& e2) noexcept+      const basic_endpoint<Protocol>& e2)   {     return !(e2 < e1);   }    /// Compare endpoints for ordering.   friend bool operator>=(const basic_endpoint<Protocol>& e1,-      const basic_endpoint<Protocol>& e2) noexcept+      const basic_endpoint<Protocol>& e2)   {     return !(e1 < e2);   }
link/modules/asio-standalone/asio/include/asio/local/connect_pair.hpp view
@@ -2,7 +2,7 @@ // local/connect_pair.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/local/datagram_protocol.hpp view
@@ -2,7 +2,7 @@ // local/datagram_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -45,19 +45,19 @@ { public:   /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return SOCK_DGRAM;   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return 0;   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return AF_UNIX;   }
link/modules/asio-standalone/asio/include/asio/local/detail/endpoint.hpp view
@@ -2,7 +2,7 @@ // local/detail/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -36,7 +36,7 @@ { public:   // Default constructor.-  ASIO_DECL endpoint() noexcept;+  ASIO_DECL endpoint();    // Construct an endpoint using the specified path name.   ASIO_DECL endpoint(const char* path_name);@@ -50,14 +50,14 @@   #endif // defined(ASIO_HAS_STRING_VIEW)    // Copy constructor.-  endpoint(const endpoint& other) noexcept+  endpoint(const endpoint& other)     : data_(other.data_),       path_length_(other.path_length_)   {   }    // Assign from another endpoint.-  endpoint& operator=(const endpoint& other) noexcept+  endpoint& operator=(const endpoint& other)   {     data_ = other.data_;     path_length_ = other.path_length_;@@ -65,19 +65,19 @@   }    // Get the underlying endpoint in the native type.-  asio::detail::socket_addr_type* data() noexcept+  asio::detail::socket_addr_type* data()   {     return &data_.base;   }    // Get the underlying endpoint in the native type.-  const asio::detail::socket_addr_type* data() const noexcept+  const asio::detail::socket_addr_type* data() const   {     return &data_.base;   }    // Get the underlying size of the endpoint in the native type.-  std::size_t size() const noexcept+  std::size_t size() const   {     return path_length_       + offsetof(asio::detail::sockaddr_un_type, sun_path);@@ -87,7 +87,7 @@   ASIO_DECL void resize(std::size_t size);    // Get the capacity of the endpoint in the native type.-  std::size_t capacity() const noexcept+  std::size_t capacity() const   {     return sizeof(asio::detail::sockaddr_un_type);   }@@ -103,11 +103,11 @@    // Compare two endpoints for equality.   ASIO_DECL friend bool operator==(-      const endpoint& e1, const endpoint& e2) noexcept;+      const endpoint& e1, const endpoint& e2);    // Compare endpoints for ordering.   ASIO_DECL friend bool operator<(-      const endpoint& e1, const endpoint& e2) noexcept;+      const endpoint& e1, const endpoint& e2);  private:   // The underlying UNIX socket address.
link/modules/asio-standalone/asio/include/asio/local/detail/impl/endpoint.ipp view
@@ -2,7 +2,7 @@ // local/detail/impl/endpoint.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Derived from a public domain implementation written by Daniel Casimiro. // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -32,7 +32,7 @@ namespace local { namespace detail { -endpoint::endpoint() noexcept+endpoint::endpoint() {   init("", 0); }@@ -93,12 +93,12 @@   init(p.data(), p.length()); } -bool operator==(const endpoint& e1, const endpoint& e2) noexcept+bool operator==(const endpoint& e1, const endpoint& e2) {   return e1.path() == e2.path(); } -bool operator<(const endpoint& e1, const endpoint& e2) noexcept+bool operator<(const endpoint& e1, const endpoint& e2) {   return e1.path() < e2.path(); }
link/modules/asio-standalone/asio/include/asio/local/seq_packet_protocol.hpp view
@@ -2,7 +2,7 @@ // local/seq_packet_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -46,19 +46,19 @@ { public:   /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return SOCK_SEQPACKET;   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return 0;   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return AF_UNIX;   }
link/modules/asio-standalone/asio/include/asio/local/stream_protocol.hpp view
@@ -2,7 +2,7 @@ // local/stream_protocol.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -47,19 +47,19 @@ { public:   /// Obtain an identifier for the type of the protocol.-  int type() const noexcept+  int type() const ASIO_NOEXCEPT   {     return SOCK_STREAM;   }    /// Obtain an identifier for the protocol.-  int protocol() const noexcept+  int protocol() const ASIO_NOEXCEPT   {     return 0;   }    /// Obtain an identifier for the protocol family.-  int family() const noexcept+  int family() const ASIO_NOEXCEPT   {     return AF_UNIX;   }
link/modules/asio-standalone/asio/include/asio/multiple_exceptions.hpp view
@@ -2,7 +2,7 @@ // multiple_exceptions.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,6 +21,9 @@  namespace asio { +#if defined(ASIO_HAS_STD_EXCEPTION_PTR) \+  || defined(GENERATING_DOCUMENTATION)+ /// Exception thrown when there are multiple pending exceptions to rethrow. class multiple_exceptions   : public std::exception@@ -28,11 +31,11 @@ public:   /// Constructor.   ASIO_DECL multiple_exceptions(-      std::exception_ptr first) noexcept;+      std::exception_ptr first) ASIO_NOEXCEPT;    /// Obtain message associated with exception.   ASIO_DECL virtual const char* what() const-    noexcept;+    ASIO_NOEXCEPT_OR_NOTHROW;    /// Obtain a pointer to the first exception.   ASIO_DECL std::exception_ptr first_exception() const;@@ -40,6 +43,9 @@ private:   std::exception_ptr first_; };++#endif // defined(ASIO_HAS_STD_EXCEPTION_PTR)+       //   || defined(GENERATING_DOCUMENTATION)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/packaged_task.hpp view
@@ -2,7 +2,7 @@ // packaged_task.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -23,11 +23,15 @@  #include "asio/async_result.hpp" #include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"  #include "asio/detail/push_options.hpp"  namespace asio { +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)+ /// Partial specialisation of @c async_result for @c std::packaged_task. template <typename Result, typename... Args, typename Signature> class async_result<std::packaged_task<Result(Args...)>, Signature>@@ -55,6 +59,62 @@ private:   return_type future_; };++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)+      //   || defined(GENERATING_DOCUMENTATION)++template <typename Result, typename Signature>+struct async_result<std::packaged_task<Result()>, Signature>+{+  typedef std::packaged_task<Result()> completion_handler_type;+  typedef std::future<Result> return_type;++  explicit async_result(completion_handler_type& h)+    : future_(h.get_future())+  {+  }++  return_type get()+  {+    return std::move(future_);+  }++private:+  return_type future_;+};++#define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \+  template <typename Result, \+    ASIO_VARIADIC_TPARAMS(n), typename Signature> \+  class async_result< \+    std::packaged_task<Result(ASIO_VARIADIC_TARGS(n))>, Signature> \+  { \+  public: \+    typedef std::packaged_task< \+      Result(ASIO_VARIADIC_TARGS(n))> \+        completion_handler_type; \+  \+    typedef std::future<Result> return_type; \+  \+    explicit async_result(completion_handler_type& h) \+      : future_(h.get_future()) \+    { \+    } \+  \+    return_type get() \+    { \+      return std::move(future_); \+    } \+  \+  private: \+    return_type future_; \+  }; \+  /**/+  ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF)+#undef ASIO_PRIVATE_ASYNC_RESULT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/placeholders.hpp view
@@ -2,7 +2,7 @@ // placeholders.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,8 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include "asio/detail/functional.hpp" +#if defined(ASIO_HAS_BOOST_BIND)+# include <boost/bind/arg.hpp>+#endif // defined(ASIO_HAS_BOOST_BIND)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -25,52 +28,119 @@  #if defined(GENERATING_DOCUMENTATION) -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the error argument of a handler for any of the asynchronous-/// functions.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the error argument of a handler for any of the asynchronous functions. unspecified error; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the bytes_transferred argument of a handler for asynchronous-/// functions such as asio::basic_stream_socket::async_write_some or+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the bytes_transferred argument of a handler for asynchronous functions such+/// as asio::basic_stream_socket::async_write_some or /// asio::async_write. unspecified bytes_transferred; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the iterator argument of a handler for asynchronous functions-/// such as asio::async_connect.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the iterator argument of a handler for asynchronous functions such as+/// asio::async_connect. unspecified iterator; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the results argument of a handler for asynchronous functions-/// such as asio::basic_resolver::async_resolve.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the results argument of a handler for asynchronous functions such as+/// asio::basic_resolver::async_resolve. unspecified results; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the results argument of a handler for asynchronous functions-/// such as asio::async_connect.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the results argument of a handler for asynchronous functions such as+/// asio::async_connect. unspecified endpoint; -/// An argument placeholder, for use with std::bind() or boost::bind(), that-/// corresponds to the signal_number argument of a handler for asynchronous-/// functions such as asio::signal_set::async_wait.+/// An argument placeholder, for use with boost::bind(), that corresponds to+/// the signal_number argument of a handler for asynchronous functions such as+/// asio::signal_set::async_wait. unspecified signal_number; -#else+#elif defined(ASIO_HAS_BOOST_BIND)+# if defined(__BORLANDC__) || defined(__GNUC__) -static ASIO_INLINE_VARIABLE constexpr auto& error-  = std::placeholders::_1;-static ASIO_INLINE_VARIABLE constexpr auto& bytes_transferred-  = std::placeholders::_2;-static ASIO_INLINE_VARIABLE constexpr auto& iterator-  = std::placeholders::_2;-static ASIO_INLINE_VARIABLE constexpr auto& results-  = std::placeholders::_2;-static ASIO_INLINE_VARIABLE constexpr auto& endpoint-  = std::placeholders::_2;-static ASIO_INLINE_VARIABLE constexpr auto& signal_number-  = std::placeholders::_2;+inline boost::arg<1> error()+{+  return boost::arg<1>();+} +inline boost::arg<2> bytes_transferred()+{+  return boost::arg<2>();+}++inline boost::arg<2> iterator()+{+  return boost::arg<2>();+}++inline boost::arg<2> results()+{+  return boost::arg<2>();+}++inline boost::arg<2> endpoint()+{+  return boost::arg<2>();+}++inline boost::arg<2> signal_number()+{+  return boost::arg<2>();+}++# else++namespace detail+{+  template <int Number>+  struct placeholder+  {+    static boost::arg<Number>& get()+    {+      static boost::arg<Number> result;+      return result;+    }+  };+}++#  if defined(ASIO_MSVC) && (ASIO_MSVC < 1400)++static boost::arg<1>& error+  = asio::placeholders::detail::placeholder<1>::get();+static boost::arg<2>& bytes_transferred+  = asio::placeholders::detail::placeholder<2>::get();+static boost::arg<2>& iterator+  = asio::placeholders::detail::placeholder<2>::get();+static boost::arg<2>& results+  = asio::placeholders::detail::placeholder<2>::get();+static boost::arg<2>& endpoint+  = asio::placeholders::detail::placeholder<2>::get();+static boost::arg<2>& signal_number+  = asio::placeholders::detail::placeholder<2>::get();++#  else++namespace+{+  boost::arg<1>& error+    = asio::placeholders::detail::placeholder<1>::get();+  boost::arg<2>& bytes_transferred+    = asio::placeholders::detail::placeholder<2>::get();+  boost::arg<2>& iterator+    = asio::placeholders::detail::placeholder<2>::get();+  boost::arg<2>& results+    = asio::placeholders::detail::placeholder<2>::get();+  boost::arg<2>& endpoint+    = asio::placeholders::detail::placeholder<2>::get();+  boost::arg<2>& signal_number+    = asio::placeholders::detail::placeholder<2>::get();+} // namespace++#  endif+# endif #endif  } // namespace placeholders
link/modules/asio-standalone/asio/include/asio/posix/basic_descriptor.hpp view
@@ -2,7 +2,7 @@ // posix/basic_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,7 +20,6 @@ #if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \   || defined(GENERATING_DOCUMENTATION) -#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp"@@ -37,6 +36,10 @@ # include "asio/detail/reactive_descriptor_service.hpp" #endif // defined(ASIO_HAS_IO_URING_AS_DEFAULT) +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -107,10 +110,10 @@    */   template <typename ExecutionContext>   explicit basic_descriptor(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {   }@@ -154,9 +157,9 @@   template <typename ExecutionContext>   basic_descriptor(ExecutionContext& context,       const native_handle_type& native_descriptor,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -165,6 +168,7 @@     asio::detail::throw_error(ec, "assign");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a descriptor from another.   /**    * This constructor moves a descriptor from one object to another.@@ -176,7 +180,7 @@    * constructed using the @c basic_descriptor(const executor_type&)    * constructor.    */-  basic_descriptor(basic_descriptor&& other) noexcept+  basic_descriptor(basic_descriptor&& other) ASIO_NOEXCEPT     : impl_(std::move(other.impl_))   {   }@@ -216,10 +220,10 @@    */   template <typename Executor1>   basic_descriptor(basic_descriptor<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(std::move(other.impl_))   {   }@@ -236,18 +240,19 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_descriptor&-  > operator=(basic_descriptor<Executor1> && other)+  >::type operator=(basic_descriptor<Executor1> && other)   {     basic_descriptor tmp(std::move(other));     impl_ = std::move(tmp.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -660,7 +665,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -696,12 +701,15 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        WaitToken = default_completion_token_t<executor_type>>-  auto async_wait(wait_type w,-      WaitToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+      void (asio::error_code))+  async_wait(wait_type w,+      ASIO_MOVE_ARG(WaitToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WaitToken, void (asio::error_code)>(-        declval<initiate_async_wait>(), token, w))+          declval<initiate_async_wait>(), token, w)))   {     return async_initiate<WaitToken, void (asio::error_code)>(         initiate_async_wait(this), token, w);@@ -726,8 +734,8 @@  private:   // Disallow copying and assignment.-  basic_descriptor(const basic_descriptor&) = delete;-  basic_descriptor& operator=(const basic_descriptor&) = delete;+  basic_descriptor(const basic_descriptor&) ASIO_DELETED;+  basic_descriptor& operator=(const basic_descriptor&) ASIO_DELETED;    class initiate_async_wait   {@@ -739,13 +747,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WaitHandler>-    void operator()(WaitHandler&& handler, wait_type w) const+    void operator()(ASIO_MOVE_ARG(WaitHandler) handler, wait_type w) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WaitHandler.
link/modules/asio-standalone/asio/include/asio/posix/basic_stream_descriptor.hpp view
@@ -2,7 +2,7 @@ // posix/basic_stream_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -95,10 +95,10 @@    */   template <typename ExecutionContext>   explicit basic_stream_descriptor(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_descriptor<Executor>(context)   {   }@@ -138,13 +138,14 @@   template <typename ExecutionContext>   basic_stream_descriptor(ExecutionContext& context,       const native_handle_type& native_descriptor,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_descriptor<Executor>(context, native_descriptor)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a stream descriptor from another.   /**    * This constructor moves a stream descriptor from one object to another.@@ -156,7 +157,7 @@    * constructed using the @c basic_stream_descriptor(const executor_type&)    * constructor.    */-  basic_stream_descriptor(basic_stream_descriptor&& other) noexcept+  basic_stream_descriptor(basic_stream_descriptor&& other) ASIO_NOEXCEPT     : basic_descriptor<Executor>(std::move(other))   {   }@@ -193,10 +194,10 @@    */   template <typename Executor1>   basic_stream_descriptor(basic_stream_descriptor<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_descriptor<Executor>(std::move(other))   {   }@@ -214,14 +215,15 @@    * constructor.    */   template <typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_stream_descriptor&-  > operator=(basic_stream_descriptor<Executor1> && other)+  >::type operator=(basic_stream_descriptor<Executor1> && other)   {     basic_descriptor<Executor>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Write some data to the descriptor.   /**@@ -307,7 +309,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -337,13 +339,17 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          initiate_async_write_some(this), token, buffers))+          initiate_async_write_some(this), token, buffers)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -436,7 +442,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -467,13 +473,17 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_read_some>(), token, buffers))+          declval<initiate_async_read_some>(), token, buffers)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -491,13 +501,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler@@ -524,13 +534,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/posix/descriptor.hpp view
@@ -2,7 +2,7 @@ // posix/descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/posix/descriptor_base.hpp view
@@ -2,7 +2,7 @@ // posix/descriptor_base.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/posix/stream_descriptor.hpp view
@@ -2,7 +2,7 @@ // posix/stream_descriptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/post.hpp view
@@ -2,7 +2,7 @@ // post.hpp // ~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -77,10 +77,11 @@  * @code void() @endcode  */ template <ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken>-inline auto post(NullaryToken&& token)-  -> decltype(+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) post(+    ASIO_MOVE_ARG(NullaryToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<NullaryToken, void()>(-      declval<detail::initiate_post>(), token))+        declval<detail::initiate_post>(), token))) {   return async_initiate<NullaryToken, void()>(       detail::initiate_post(), token);@@ -157,17 +158,19 @@  */ template <typename Executor,     ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken-      = default_completion_token_t<Executor>>-inline auto post(const Executor& ex,-    NullaryToken&& token = default_completion_token_t<Executor>(),-    constraint_t<+      ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) post(+    const Executor& ex,+    ASIO_MOVE_ARG(NullaryToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+    typename constraint<       (execution::is_executor<Executor>::value           && can_require<Executor, execution::blocking_t::never_t>::value)         || is_executor<Executor>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<NullaryToken, void()>(-      declval<detail::initiate_post_with_executor<Executor>>(), token))+        declval<detail::initiate_post_with_executor<Executor> >(), token))) {   return async_initiate<NullaryToken, void()>(       detail::initiate_post_with_executor<Executor>(ex), token);@@ -188,17 +191,19 @@  */ template <typename ExecutionContext,     ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken-      = default_completion_token_t<typename ExecutionContext::executor_type>>-inline auto post(ExecutionContext& ctx,-    NullaryToken&& token = default_completion_token_t<-      typename ExecutionContext::executor_type>(),-    constraint_t<-      is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)-  -> decltype(+      ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+        typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(NullaryToken, void()) post(+    ExecutionContext& ctx,+    ASIO_MOVE_ARG(NullaryToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename ExecutionContext::executor_type),+    typename constraint<is_convertible<+      ExecutionContext&, execution_context&>::value>::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<NullaryToken, void()>(-      declval<detail::initiate_post_with_executor<-        typename ExecutionContext::executor_type>>(), token))+        declval<detail::initiate_post_with_executor<+          typename ExecutionContext::executor_type> >(), token))) {   return async_initiate<NullaryToken, void()>(       detail::initiate_post_with_executor<
link/modules/asio-standalone/asio/include/asio/prefer.hpp view
@@ -2,7 +2,7 @@ // prefer.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -118,10 +118,10 @@  namespace asio_prefer_fn { -using asio::conditional_t;-using asio::decay_t;+using asio::conditional;+using asio::decay; using asio::declval;-using asio::enable_if_t;+using asio::enable_if; using asio::is_applicable_property; using asio::traits::prefer_free; using asio::traits::prefer_member;@@ -149,187 +149,195 @@     typename = void, typename = void, typename = void> struct call_traits {-  static constexpr overload_type overload = ill_formed;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_preferable-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_preferable+  >::type,+  typename enable_if<     static_require<T, Property>::is_valid-  >>+  >::type> {-  static constexpr overload_type overload = identity;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); -  typedef T&& result_type;+#if defined(ASIO_HAS_MOVE)+  typedef ASIO_MOVE_ARG(T) result_type;+#else // defined(ASIO_HAS_MOVE)+  typedef ASIO_MOVE_ARG(typename decay<T>::type) result_type;+#endif // defined(ASIO_HAS_MOVE) };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_preferable-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_preferable+  >::type,+  typename enable_if<     !static_require<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     require_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >> :+  >::type> :   require_member<typename Impl::template proxy<T>::type, Property> {-  static constexpr overload_type overload = call_require_member;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_member); };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_preferable-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_preferable+  >::type,+  typename enable_if<     !static_require<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     require_free<T, Property>::is_valid-  >> :+  >::type> :   require_free<T, Property> {-  static constexpr overload_type overload = call_require_free;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_require_free); };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_preferable-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_preferable+  >::type,+  typename enable_if<     !static_require<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !require_free<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >> :+  >::type> :   prefer_member<typename Impl::template proxy<T>::type, Property> {-  static constexpr overload_type overload = call_prefer_member;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_member); };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_preferable-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_preferable+  >::type,+  typename enable_if<     !static_require<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !require_free<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     prefer_free<T, Property>::is_valid-  >> :+  >::type> :   prefer_free<T, Property> {-  static constexpr overload_type overload = call_prefer_free;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_prefer_free); };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_preferable-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_preferable+  >::type,+  typename enable_if<     !static_require<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !require_free<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !prefer_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !prefer_free<T, Property>::is_valid-  >>+  >::type> {-  static constexpr overload_type overload = identity;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); -  typedef T&& result_type;+#if defined(ASIO_HAS_MOVE)+  typedef ASIO_MOVE_ARG(T) result_type;+#else // defined(ASIO_HAS_MOVE)+  typedef ASIO_MOVE_ARG(typename decay<T>::type) result_type;+#endif // defined(ASIO_HAS_MOVE) };  template <typename Impl, typename T, typename P0, typename P1> struct call_traits<Impl, T, void(P0, P1),-  enable_if_t<+  typename enable_if<     call_traits<Impl, T, void(P0)>::overload != ill_formed-  >,-  enable_if_t<+  >::type,+  typename enable_if<     call_traits<       Impl,       typename call_traits<Impl, T, void(P0)>::result_type,       void(P1)     >::overload != ill_formed-  >>+  >::type> {-  static constexpr overload_type overload = two_props;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = two_props); -  static constexpr bool is_noexcept =+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =     (       call_traits<Impl, T, void(P0)>::is_noexcept       &&@@ -338,51 +346,51 @@         typename call_traits<Impl, T, void(P0)>::result_type,         void(P1)       >::is_noexcept-    );+    )); -  typedef decay_t<+  typedef typename decay<     typename call_traits<       Impl,       typename call_traits<Impl, T, void(P0)>::result_type,       void(P1)     >::result_type-  > result_type;+  >::type result_type; };  template <typename Impl, typename T, typename P0,-    typename P1, typename... PN>-struct call_traits<Impl, T, void(P0, P1, PN...),-  enable_if_t<+    typename P1, typename ASIO_ELLIPSIS PN>+struct call_traits<Impl, T, void(P0, P1, PN ASIO_ELLIPSIS),+  typename enable_if<     call_traits<Impl, T, void(P0)>::overload != ill_formed-  >,-  enable_if_t<+  >::type,+  typename enable_if<     call_traits<       Impl,       typename call_traits<Impl, T, void(P0)>::result_type,-      void(P1, PN...)+      void(P1, PN ASIO_ELLIPSIS)     >::overload != ill_formed-  >>+  >::type> {-  static constexpr overload_type overload = n_props;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = n_props); -  static constexpr bool is_noexcept =+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =     (       call_traits<Impl, T, void(P0)>::is_noexcept       &&       call_traits<         Impl,         typename call_traits<Impl, T, void(P0)>::result_type,-        void(P1, PN...)+        void(P1, PN ASIO_ELLIPSIS)       >::is_noexcept-    );+    )); -  typedef decay_t<+  typedef typename decay<     typename call_traits<       Impl,       typename call_traits<Impl, T, void(P0)>::result_type,-      void(P1, PN...)+      void(P1, PN ASIO_ELLIPSIS)     >::result_type-  > result_type;+  >::type result_type; };  struct impl@@ -395,25 +403,29 @@     struct type     {       template <typename P>-      auto require(P&& p)+      auto require(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().require(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().require(+            ASIO_MOVE_CAST(P)(p))         );        template <typename P>-      auto prefer(P&& p)+      auto prefer(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().prefer(static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().prefer(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().prefer(static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().prefer(+            ASIO_MOVE_CAST(P)(p))         );     }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -424,85 +436,122 @@   };    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == identity,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&&) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property)) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return static_cast<T&&>(t);+    return ASIO_MOVE_CAST(T)(t);   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_require_member,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return static_cast<T&&>(t).require(static_cast<Property&&>(p));+    return ASIO_MOVE_CAST(T)(t).require(+        ASIO_MOVE_CAST(Property)(p));   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_require_free,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return require(static_cast<T&&>(t), static_cast<Property&&>(p));+    return require(+        ASIO_MOVE_CAST(T)(t),+        ASIO_MOVE_CAST(Property)(p));   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_prefer_member,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return static_cast<T&&>(t).prefer(static_cast<Property&&>(p));+    return ASIO_MOVE_CAST(T)(t).prefer(+        ASIO_MOVE_CAST(Property)(p));   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_prefer_free,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return prefer(static_cast<T&&>(t), static_cast<Property&&>(p));+    return prefer(+        ASIO_MOVE_CAST(T)(t),+        ASIO_MOVE_CAST(Property)(p));   }    template <typename T, typename P0, typename P1>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(P0, P1)>::overload == two_props,     typename call_traits<impl, T, void(P0, P1)>::result_type-  >-  operator()(T&& t, P0&& p0, P1&& p1) const-    noexcept(call_traits<impl, T, void(P0, P1)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(P0) p0,+      ASIO_MOVE_ARG(P1) p1) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(P0, P1)>::is_noexcept))   {     return (*this)(-        (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),-        static_cast<P1&&>(p1));+        (*this)(+          ASIO_MOVE_CAST(T)(t),+          ASIO_MOVE_CAST(P0)(p0)),+        ASIO_MOVE_CAST(P1)(p1));   }    template <typename T, typename P0, typename P1,-    typename... PN>-  ASIO_NODISCARD constexpr enable_if_t<-    call_traits<impl, T, void(P0, P1, PN...)>::overload == n_props,-    typename call_traits<impl, T, void(P0, P1, PN...)>::result_type-  >-  operator()(T&& t, P0&& p0, P1&& p1, PN&&... pn) const-    noexcept(call_traits<impl, T, void(P0, P1, PN...)>::is_noexcept)+    typename ASIO_ELLIPSIS PN>+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+    call_traits<impl, T,+      void(P0, P1, PN ASIO_ELLIPSIS)>::overload == n_props,+    typename call_traits<impl, T,+      void(P0, P1, PN ASIO_ELLIPSIS)>::result_type+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(P0) p0,+      ASIO_MOVE_ARG(P1) p1,+      ASIO_MOVE_ARG(PN) ASIO_ELLIPSIS pn) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(P0, P1, PN ASIO_ELLIPSIS)>::is_noexcept))   {     return (*this)(-        (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),-        static_cast<P1&&>(p1), static_cast<PN&&>(pn)...);+        (*this)(+          ASIO_MOVE_CAST(T)(t),+          ASIO_MOVE_CAST(P0)(p0)),+        ASIO_MOVE_CAST(P1)(p1),+        ASIO_MOVE_CAST(PN)(pn) ASIO_ELLIPSIS);   } }; @@ -519,13 +568,15 @@ namespace asio { namespace { -static constexpr const asio_prefer_fn::impl&+static ASIO_CONSTEXPR const asio_prefer_fn::impl&   prefer = asio_prefer_fn::static_instance<>::instance;  } // namespace  typedef asio_prefer_fn::impl prefer_t; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct can_prefer :   integral_constant<bool,@@ -535,14 +586,54 @@ { }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+    typename P1 = void, typename P2 = void>+struct can_prefer :+  integral_constant<bool,+    asio_prefer_fn::call_traits<+      prefer_t, T, void(P0, P1, P2)>::overload+        != asio_prefer_fn::ill_formed>+{+};++template <typename T, typename P0, typename P1>+struct can_prefer<T, P0, P1> :+  integral_constant<bool,+    asio_prefer_fn::call_traits<+      prefer_t, T, void(P0, P1)>::overload+        != asio_prefer_fn::ill_formed>+{+};++template <typename T, typename P0>+struct can_prefer<T, P0> :+  integral_constant<bool,+    asio_prefer_fn::call_traits<+      prefer_t, T, void(P0)>::overload+        != asio_prefer_fn::ill_formed>+{+};++template <typename T>+struct can_prefer<T> :+  false_type+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) -template <typename T, typename... Properties>+template <typename T, typename ASIO_ELLIPSIS Properties> constexpr bool can_prefer_v-  = can_prefer<T, Properties...>::value;+  = can_prefer<T, Properties ASIO_ELLIPSIS>::value;  #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct is_nothrow_prefer :   integral_constant<bool,@@ -551,13 +642,51 @@ { }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+    typename P1 = void, typename P2 = void>+struct is_nothrow_prefer :+  integral_constant<bool,+    asio_prefer_fn::call_traits<+      prefer_t, T, void(P0, P1, P2)>::is_noexcept>+{+};++template <typename T, typename P0, typename P1>+struct is_nothrow_prefer<T, P0, P1> :+  integral_constant<bool,+    asio_prefer_fn::call_traits<+      prefer_t, T, void(P0, P1)>::is_noexcept>+{+};++template <typename T, typename P0>+struct is_nothrow_prefer<T, P0> :+  integral_constant<bool,+    asio_prefer_fn::call_traits<+      prefer_t, T, void(P0)>::is_noexcept>+{+};++template <typename T>+struct is_nothrow_prefer<T> :+  false_type+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) -template <typename T, typename... Properties>-constexpr bool is_nothrow_prefer_v = is_nothrow_prefer<T, Properties...>::value;+template <typename T, typename ASIO_ELLIPSIS Properties>+constexpr bool is_nothrow_prefer_v+  = is_nothrow_prefer<T, Properties ASIO_ELLIPSIS>::value;  #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct prefer_result {@@ -565,8 +694,36 @@       prefer_t, T, void(Properties...)>::result_type type; }; -template <typename T, typename... Properties>-using prefer_result_t = typename prefer_result<T, Properties...>::type;+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+    typename P1 = void, typename P2 = void>+struct prefer_result+{+  typedef typename asio_prefer_fn::call_traits<+      prefer_t, T, void(P0, P1, P2)>::result_type type;+};++template <typename T, typename P0, typename P1>+struct prefer_result<T, P0, P1>+{+  typedef typename asio_prefer_fn::call_traits<+      prefer_t, T, void(P0, P1)>::result_type type;+};++template <typename T, typename P0>+struct prefer_result<T, P0>+{+  typedef typename asio_prefer_fn::call_traits<+      prefer_t, T, void(P0)>::result_type type;+};++template <typename T>+struct prefer_result<T>+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/prepend.hpp view
@@ -2,7 +2,7 @@ // prepend.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,11 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if (defined(ASIO_HAS_STD_TUPLE) \+    && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \+  || defined(GENERATING_DOCUMENTATION)+ #include <tuple> #include "asio/detail/type_traits.hpp" @@ -32,9 +37,11 @@ public:   /// Constructor.   template <typename T, typename... V>-  constexpr explicit prepend_t(T&& completion_token, V&&... values)-    : token_(static_cast<T&&>(completion_token)),-      values_(static_cast<V&&>(values)...)+  ASIO_CONSTEXPR explicit prepend_t(+      ASIO_MOVE_ARG(T) completion_token,+      ASIO_MOVE_ARG(V)... values)+    : token_(ASIO_MOVE_CAST(T)(completion_token)),+      values_(ASIO_MOVE_CAST(V)(values)...)   {   } @@ -47,14 +54,15 @@ /// arguments should be passed additional values before the results of the /// operation. template <typename CompletionToken, typename... Values>-ASIO_NODISCARD inline constexpr-prepend_t<decay_t<CompletionToken>, decay_t<Values>...>-prepend(CompletionToken&& completion_token,-    Values&&... values)+ASIO_NODISCARD inline ASIO_CONSTEXPR prepend_t<+  typename decay<CompletionToken>::type, typename decay<Values>::type...>+prepend(ASIO_MOVE_ARG(CompletionToken) completion_token,+    ASIO_MOVE_ARG(Values)... values) {-  return prepend_t<decay_t<CompletionToken>, decay_t<Values>...>(-      static_cast<CompletionToken&&>(completion_token),-      static_cast<Values&&>(values)...);+  return prepend_t<+    typename decay<CompletionToken>::type, typename decay<Values>::type...>(+      ASIO_MOVE_CAST(CompletionToken)(completion_token),+      ASIO_MOVE_CAST(Values)(values)...); }  } // namespace asio@@ -62,5 +70,9 @@ #include "asio/detail/pop_options.hpp"  #include "asio/impl/prepend.hpp"++#endif // (defined(ASIO_HAS_STD_TUPLE)+       //     && defined(ASIO_HAS_VARIADIC_TEMPLATES))+       //   || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_PREPEND_HPP
link/modules/asio-standalone/asio/include/asio/query.hpp view
@@ -2,7 +2,7 @@ // query.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -100,10 +100,10 @@  namespace asio_query_fn { -using asio::conditional_t;-using asio::decay_t;+using asio::conditional;+using asio::decay; using asio::declval;-using asio::enable_if_t;+using asio::enable_if; using asio::is_applicable_property; using asio::traits::query_free; using asio::traits::query_member;@@ -123,66 +123,66 @@     typename = void, typename = void, typename = void, typename = void> struct call_traits {-  static constexpr overload_type overload = ill_formed;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<+  >::type,+  typename enable_if<     static_query<T, Property>::is_valid-  >> :+  >::type> :   static_query<T, Property> {-  static constexpr overload_type overload = static_value;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = static_value); };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !static_query<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     query_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >> :+  >::type> :   query_member<typename Impl::template proxy<T>::type, Property> {-  static constexpr overload_type overload = call_member;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !static_query<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !query_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     query_free<T, Property>::is_valid-  >> :+  >::type> :   query_free<T, Property> {-  static constexpr overload_type overload = call_free;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); };  struct impl@@ -194,14 +194,16 @@     struct type     {       template <typename P>-      auto query(P&& p)+      auto query(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().query(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().query(static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().query(+            ASIO_MOVE_CAST(P)(p))         );     }; #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -210,36 +212,48 @@   };    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == static_value,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&&, Property&&) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T),+      ASIO_MOVE_ARG(Property)) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return static_query<decay_t<T>, decay_t<Property>>::value();+    return static_query<+      typename decay<T>::type,+      typename decay<Property>::type+    >::value();   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_member,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return static_cast<T&&>(t).query(static_cast<Property&&>(p));+    return ASIO_MOVE_CAST(T)(t).query(ASIO_MOVE_CAST(Property)(p));   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_free,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return query(static_cast<T&&>(t), static_cast<Property&&>(p));+    return query(ASIO_MOVE_CAST(T)(t), ASIO_MOVE_CAST(Property)(p));   } }; @@ -256,7 +270,7 @@ namespace asio { namespace { -static constexpr const asio_query_fn::impl&+static ASIO_CONSTEXPR const asio_query_fn::impl&   query = asio_query_fn::static_instance<>::instance;  } // namespace@@ -274,7 +288,8 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES)  template <typename T, typename Property>-constexpr bool can_query_v = can_query<T, Property>::value;+constexpr bool can_query_v+  = can_query<T, Property>::value;  #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) @@ -288,7 +303,8 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES)  template <typename T, typename Property>-constexpr bool is_nothrow_query_v = is_nothrow_query<T, Property>::value;+constexpr bool is_nothrow_query_v+  = is_nothrow_query<T, Property>::value;  #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) @@ -298,9 +314,6 @@   typedef typename asio_query_fn::call_traits<       query_t, T, void(Property)>::result_type type; };--template <typename T, typename Property>-using query_result_t = typename query_result<T, Property>::type;  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/random_access_file.hpp view
@@ -2,7 +2,7 @@ // random_access_file.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/read.hpp view
@@ -2,7 +2,7 @@ // read.hpp // ~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -85,9 +85,9 @@  */ template <typename SyncReadStream, typename MutableBufferSequence> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,-    constraint_t<+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    > = 0);+    >::type = 0);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -128,9 +128,9 @@ template <typename SyncReadStream, typename MutableBufferSequence> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,     asio::error_code& ec,-    constraint_t<+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    > = 0);+    >::type = 0);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -182,12 +182,9 @@   typename CompletionCondition> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,     CompletionCondition completion_condition,-    constraint_t<+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    >::type = 0);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -232,12 +229,9 @@     typename CompletionCondition> std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    >::type = 0);  #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -270,13 +264,13 @@  */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -306,14 +300,14 @@  */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -354,17 +348,14 @@ template <typename SyncReadStream, typename DynamicBuffer_v1,     typename CompletionCondition> std::size_t read(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -406,17 +397,14 @@ template <typename SyncReadStream, typename DynamicBuffer_v1,     typename CompletionCondition> std::size_t read(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -518,10 +506,7 @@ template <typename SyncReadStream, typename Allocator,     typename CompletionCondition> std::size_t read(SyncReadStream& s, basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -562,10 +547,7 @@ template <typename SyncReadStream, typename Allocator,     typename CompletionCondition> std::size_t read(SyncReadStream& s, basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition, asio::error_code& ec);  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -600,9 +582,9 @@  */ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -633,9 +615,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,     asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -677,12 +659,9 @@     typename CompletionCondition> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    >::type = 0);  /// Attempt to read a certain amount of data from a stream before returning. /**@@ -725,12 +704,9 @@     typename CompletionCondition> std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    >::type = 0);  /*@}*/ /**@@ -786,7 +762,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -819,28 +795,23 @@  */ template <typename AsyncReadStream, typename MutableBufferSequence,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    > = 0,-    constraint_t<-      !is_completion_condition<ReadToken>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read<AsyncReadStream>>(),-        token, buffers, transfer_all()))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read<AsyncReadStream>(s),-      token, buffers, transfer_all());-}+        declval<detail::initiate_async_read<AsyncReadStream> >(),+        token, buffers, transfer_all())));  /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -895,7 +866,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -924,30 +895,25 @@ template <typename AsyncReadStream,     typename MutableBufferSequence, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,     CompletionCondition completion_condition,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<       is_mutable_buffer_sequence<MutableBufferSequence>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read<AsyncReadStream>>(),+        declval<detail::initiate_async_read<AsyncReadStream> >(),         token, buffers,-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read<AsyncReadStream>(s), token, buffers,-      static_cast<CompletionCondition&&>(completion_condition));-}+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -995,7 +961,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1019,31 +985,28 @@  */ template <typename AsyncReadStream, typename DynamicBuffer_v1,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, DynamicBuffer_v1&& buffers,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_completion_condition<ReadToken>::value-    > = 0)-  -> decltype(+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v1&&>(buffers), transfer_all()))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v1&&>(buffers), transfer_all());-}+        declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        transfer_all())));  /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -1103,7 +1066,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1122,34 +1085,29 @@ template <typename AsyncReadStream,     typename DynamicBuffer_v1, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, DynamicBuffer_v1&& buffers,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v1&&>(buffers),-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v1&&>(buffers),-      static_cast<CompletionCondition&&>(completion_condition));-}+        declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -1196,7 +1154,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1220,25 +1178,18 @@  */ template <typename AsyncReadStream, typename Allocator,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<-      !is_completion_condition<ReadToken>::value-    > = 0)-  -> decltype(-    async_initiate<ReadToken,-      void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream>>(),-        token, basic_streambuf_ref<Allocator>(b), transfer_all()))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),-      token, basic_streambuf_ref<Allocator>(b), transfer_all());-}+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read(s, basic_streambuf_ref<Allocator>(b),+        ASIO_MOVE_CAST(ReadToken)(token))));  /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -1296,7 +1247,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1315,28 +1266,20 @@ template <typename AsyncReadStream,     typename Allocator, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,     CompletionCondition completion_condition,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(-    async_initiate<ReadToken,-      void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_dynbuf_v1<AsyncReadStream>>(),-        token, basic_streambuf_ref<Allocator>(b),-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_dynbuf_v1<AsyncReadStream>(s),-      token, basic_streambuf_ref<Allocator>(b),-      static_cast<CompletionCondition&&>(completion_condition));-}+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read(s, basic_streambuf_ref<Allocator>(b),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+        ASIO_MOVE_CAST(ReadToken)(token))));  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -1386,7 +1329,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1410,28 +1353,24 @@  */ template <typename AsyncReadStream, typename DynamicBuffer_v2,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0,-    constraint_t<-      !is_completion_condition<ReadToken>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v2&&>(buffers), transfer_all()))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v2&&>(buffers), transfer_all());-}+        declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        transfer_all())));  /// Start an asynchronous operation to read a certain amount of data from a /// stream.@@ -1491,7 +1430,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1510,31 +1449,25 @@ template <typename AsyncReadStream,     typename DynamicBuffer_v2, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v2&&>(buffers),-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_dynbuf_v2<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v2&&>(buffers),-      static_cast<CompletionCondition&&>(completion_condition));-}+        declval<detail::initiate_async_read_dynbuf_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  /*@}*/ 
link/modules/asio-standalone/asio/include/asio/read_at.hpp view
@@ -2,7 +2,7 @@ // read_at.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -190,10 +190,7 @@     typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d,     uint64_t offset, const MutableBufferSequence& buffers,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition);  /// Attempt to read a certain amount of data at the specified offset before /// returning.@@ -242,10 +239,7 @@     typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d,     uint64_t offset, const MutableBufferSequence& buffers,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition, asio::error_code& ec);  #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -356,10 +350,7 @@     typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d,     uint64_t offset, basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition);  /// Attempt to read a certain amount of data at the specified offset before /// returning.@@ -403,10 +394,7 @@     typename CompletionCondition> std::size_t read_at(SyncRandomAccessReadDevice& d,     uint64_t offset, basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition, asio::error_code& ec);  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -465,7 +453,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -498,26 +486,21 @@  */ template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncRandomAccessReadDevice::executor_type>>-inline auto async_read_at(AsyncRandomAccessReadDevice& d,-    uint64_t offset, const MutableBufferSequence& buffers,-    ReadToken&& token = default_completion_token_t<-      typename AsyncRandomAccessReadDevice::executor_type>(),-    constraint_t<-      !is_completion_condition<ReadToken>::value-    > = 0)-  -> decltype(+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncRandomAccessReadDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,+    const MutableBufferSequence& buffers,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncRandomAccessReadDevice::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice>>(),-        token, offset, buffers, transfer_all()))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),-      token, offset, buffers, transfer_all());-}+        declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),+        token, offset, buffers, transfer_all())));  /// Start an asynchronous operation to read a certain amount of data at the /// specified offset.@@ -575,7 +558,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -604,29 +587,23 @@ template <typename AsyncRandomAccessReadDevice,     typename MutableBufferSequence, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncRandomAccessReadDevice::executor_type>>-inline auto async_read_at(AsyncRandomAccessReadDevice& d,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncRandomAccessReadDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,     uint64_t offset, const MutableBufferSequence& buffers,     CompletionCondition completion_condition,-    ReadToken&& token = default_completion_token_t<-      typename AsyncRandomAccessReadDevice::executor_type>(),-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncRandomAccessReadDevice::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice>>(),+        declval<detail::initiate_async_read_at<AsyncRandomAccessReadDevice> >(),         token, offset, buffers,-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_at<AsyncRandomAccessReadDevice>(d),-      token, offset, buffers,-      static_cast<CompletionCondition&&>(completion_condition));-}+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -671,7 +648,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -695,27 +672,22 @@  */ template <typename AsyncRandomAccessReadDevice, typename Allocator,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncRandomAccessReadDevice::executor_type>>-inline auto async_read_at(AsyncRandomAccessReadDevice& d,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncRandomAccessReadDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,     uint64_t offset, basic_streambuf<Allocator>& b,-    ReadToken&& token = default_completion_token_t<-      typename AsyncRandomAccessReadDevice::executor_type>(),-    constraint_t<-      !is_completion_condition<ReadToken>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncRandomAccessReadDevice::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(         declval<detail::initiate_async_read_at_streambuf<-          AsyncRandomAccessReadDevice>>(),-        token, offset, &b, transfer_all()))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),-      token, offset, &b, transfer_all());-}+          AsyncRandomAccessReadDevice> >(),+        token, offset, &b, transfer_all())));  /// Start an asynchronous operation to read a certain amount of data at the /// specified offset.@@ -771,7 +743,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -790,29 +762,24 @@ template <typename AsyncRandomAccessReadDevice,     typename Allocator, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncRandomAccessReadDevice::executor_type>>-inline auto async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,-    basic_streambuf<Allocator>& b, CompletionCondition completion_condition,-    ReadToken&& token = default_completion_token_t<-      typename AsyncRandomAccessReadDevice::executor_type>(),-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncRandomAccessReadDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_at(AsyncRandomAccessReadDevice& d,+    uint64_t offset, basic_streambuf<Allocator>& b,+    CompletionCondition completion_condition,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncRandomAccessReadDevice::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(         declval<detail::initiate_async_read_at_streambuf<-          AsyncRandomAccessReadDevice>>(),+          AsyncRandomAccessReadDevice> >(),         token, offset, &b,-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_at_streambuf<AsyncRandomAccessReadDevice>(d),-      token, offset, &b,-      static_cast<CompletionCondition&&>(completion_condition));-}+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/read_until.hpp view
@@ -2,7 +2,7 @@ // read_until.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -73,7 +73,8 @@ #else   enum   {-    value = asio::is_function<remove_pointer_t<T>>::value+    value = asio::is_function<+        typename asio::remove_pointer<T>::type>::value       || detail::has_result_type<T>::value   }; #endif@@ -146,13 +147,13 @@  */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers, char delim,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -190,14 +191,14 @@  */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     char delim, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -252,14 +253,14 @@  */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     ASIO_STRING_VIEW_PARAM delim,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -297,15 +298,15 @@  */ template <typename SyncReadStream, typename DynamicBuffer_v1> std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     ASIO_STRING_VIEW_PARAM delim,     asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -365,15 +366,16 @@  * This data may be the start of a new line, to be extracted by a subsequent  * @c read_until operation.  */-template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,-    const boost::basic_regex<char, Traits>& expr,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    const boost::regex& expr,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression.@@ -411,15 +413,16 @@  * expression. An application will typically leave that data in the dynamic  * buffer sequence for a subsequent read_until operation to examine.  */-template <typename SyncReadStream, typename DynamicBuffer_v1, typename Traits>-std::size_t read_until(SyncReadStream& s, DynamicBuffer_v1&& buffers,-    const boost::basic_regex<char, Traits>& expr, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+template <typename SyncReadStream, typename DynamicBuffer_v1>+std::size_t read_until(SyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    const boost::regex& expr, asio::error_code& ec,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  #endif // defined(ASIO_HAS_BOOST_REGEX)        // || defined(GENERATING_DOCUMENTATION)@@ -480,7 +483,7 @@  * @par Examples  * To read data into a dynamic buffer sequence until whitespace is encountered:  * @code typedef asio::buffers_iterator<- *     asio::const_buffer> iterator;+ *     asio::const_buffers_1> iterator;  *  * std::pair<iterator, bool>  * match_whitespace(iterator begin, iterator end)@@ -529,17 +532,17 @@ template <typename SyncReadStream,     typename DynamicBuffer_v1, typename MatchCondition> std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     MatchCondition match_condition,-    constraint_t<+    typename constraint<       is_match_condition<MatchCondition>::value-    > = 0,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    >::type = 0,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Read data into a dynamic buffer sequence until a function object indicates a /// match.@@ -597,17 +600,17 @@ template <typename SyncReadStream,     typename DynamicBuffer_v1, typename MatchCondition> std::size_t read_until(SyncReadStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     MatchCondition match_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_match_condition<MatchCondition>::value-    > = 0,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    >::type = 0,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  #if !defined(ASIO_NO_IOSTREAM) @@ -839,10 +842,9 @@  * This data may be the start of a new line, to be extracted by a subsequent  * @c read_until operation.  */-template <typename SyncReadStream, typename Allocator, typename Traits>+template <typename SyncReadStream, typename Allocator> std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b,-    const boost::basic_regex<char, Traits>& expr);+    asio::basic_streambuf<Allocator>& b, const boost::regex& expr);  /// Read data into a streambuf until some part of the data it contains matches /// a regular expression.@@ -877,10 +879,9 @@  * application will typically leave that data in the streambuf for a subsequent  * read_until operation to examine.  */-template <typename SyncReadStream, typename Allocator, typename Traits>+template <typename SyncReadStream, typename Allocator> std::size_t read_until(SyncReadStream& s,-    asio::basic_streambuf<Allocator>& b,-    const boost::basic_regex<char, Traits>& expr,+    asio::basic_streambuf<Allocator>& b, const boost::regex& expr,     asio::error_code& ec);  #endif // defined(ASIO_HAS_BOOST_REGEX)@@ -989,7 +990,7 @@ template <typename SyncReadStream, typename Allocator, typename MatchCondition> std::size_t read_until(SyncReadStream& s,     asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,-    constraint_t<is_match_condition<MatchCondition>::value> = 0);+    typename constraint<is_match_condition<MatchCondition>::value>::type = 0);  /// Read data into a streambuf until a function object indicates a match. /**@@ -1046,7 +1047,7 @@ std::size_t read_until(SyncReadStream& s,     asio::basic_streambuf<Allocator>& b,     MatchCondition match_condition, asio::error_code& ec,-    constraint_t<is_match_condition<MatchCondition>::value> = 0);+    typename constraint<is_match_condition<MatchCondition>::value>::type = 0);  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -1107,9 +1108,9 @@  */ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -1148,9 +1149,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,     char delim, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -1206,9 +1207,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,     ASIO_STRING_VIEW_PARAM delim,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  /// Read data into a dynamic buffer sequence until it contains a specified /// delimiter.@@ -1247,9 +1248,9 @@ template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,     ASIO_STRING_VIEW_PARAM delim, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -1309,12 +1310,12 @@  * This data may be the start of a new line, to be extracted by a subsequent  * @c read_until operation.  */-template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>+template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,-    const boost::basic_regex<char, Traits>& expr,-    constraint_t<+    const boost::regex& expr,+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  /// Read data into a dynamic buffer sequence until some part of the data it /// contains matches a regular expression.@@ -1352,12 +1353,12 @@  * expression. An application will typically leave that data in the dynamic  * buffer sequence for a subsequent read_until operation to examine.  */-template <typename SyncReadStream, typename DynamicBuffer_v2, typename Traits>+template <typename SyncReadStream, typename DynamicBuffer_v2> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,-    const boost::basic_regex<char, Traits>& expr, asio::error_code& ec,-    constraint_t<+    const boost::regex& expr, asio::error_code& ec,+    typename constraint<         is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  #endif // defined(ASIO_HAS_BOOST_REGEX)        // || defined(GENERATING_DOCUMENTATION)@@ -1418,7 +1419,7 @@  * @par Examples  * To read data into a dynamic buffer sequence until whitespace is encountered:  * @code typedef asio::buffers_iterator<- *     asio::const_buffer> iterator;+ *     asio::const_buffers_1> iterator;  *  * std::pair<iterator, bool>  * match_whitespace(iterator begin, iterator end)@@ -1468,12 +1469,12 @@     typename DynamicBuffer_v2, typename MatchCondition> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,     MatchCondition match_condition,-    constraint_t<+    typename constraint<       is_match_condition<MatchCondition>::value-    > = 0,-    constraint_t<+    >::type = 0,+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  /// Read data into a dynamic buffer sequence until a function object indicates a /// match.@@ -1532,12 +1533,12 @@     typename DynamicBuffer_v2, typename MatchCondition> std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,     MatchCondition match_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_match_condition<MatchCondition>::value-    > = 0,-    constraint_t<+    >::type = 0,+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  #endif // !defined(ASIO_NO_EXTENSIONS) @@ -1602,7 +1603,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1653,29 +1654,27 @@  */ template <typename AsyncReadStream, typename DynamicBuffer_v1,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,-    DynamicBuffer_v1&& buffers, char delim,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0)-  -> decltype(+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v1&&>(buffers), delim))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v1&&>(buffers), delim);-}+        declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim)));  /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter.@@ -1725,7 +1724,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1776,33 +1775,30 @@  */ template <typename AsyncReadStream, typename DynamicBuffer_v1,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,-    DynamicBuffer_v1&& buffers,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     ASIO_STRING_VIEW_PARAM delim,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(         declval<detail::initiate_async_read_until_delim_string_v1<-          AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v1&&>(buffers),-        static_cast<std::string>(delim)))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v1&&>(buffers),-      static_cast<std::string>(delim));-}+          AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        static_cast<std::string>(delim))));  #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -1860,7 +1856,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1910,31 +1906,30 @@  * if they are also supported by the @c AsyncReadStream type's  * @c async_read_some operation.  */-template <typename AsyncReadStream, typename DynamicBuffer_v1, typename Traits,+template <typename AsyncReadStream, typename DynamicBuffer_v1,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v1&& buffers,-    const boost::basic_regex<char, Traits>& expr,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0)-  -> decltype(+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    const boost::regex& expr,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v1&&>(buffers), expr))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v1&&>(buffers), expr);-}+        declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr)));  #endif // defined(ASIO_HAS_BOOST_REGEX)        // || defined(GENERATING_DOCUMENTATION)@@ -2002,7 +1997,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @note After a successful async_read_until operation, the dynamic buffer  * sequence may contain additional data beyond that which matched the function@@ -2021,7 +2016,7 @@  * To asynchronously read data into a @c std::string until whitespace is  * encountered:  * @code typedef asio::buffers_iterator<- *     asio::const_buffer> iterator;+ *     asio::const_buffers_1> iterator;  *  * std::pair<iterator, bool>  * match_whitespace(iterator begin, iterator end)@@ -2086,34 +2081,32 @@ template <typename AsyncReadStream,     typename DynamicBuffer_v1, typename MatchCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,-    DynamicBuffer_v1&& buffers, MatchCondition match_condition,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    MatchCondition match_condition,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<       is_match_condition<MatchCondition>::value-    > = 0,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0)-  -> decltype(+    >::type = 0,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_match_v1<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v1&&>(buffers),-        match_condition))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_match_v1<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v1&&>(buffers),-      match_condition);-}+        declval<detail::initiate_async_read_until_match_v1<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        match_condition)));  #if !defined(ASIO_NO_IOSTREAM) @@ -2164,7 +2157,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -2214,23 +2207,19 @@  */ template <typename AsyncReadStream, typename Allocator,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,     asio::basic_streambuf<Allocator>& b, char delim,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>())-  -> decltype(-    async_initiate<ReadToken,-      void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_delim_v1<AsyncReadStream>>(),-        token, basic_streambuf_ref<Allocator>(b), delim))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_delim_v1<AsyncReadStream>(s),-      token, basic_streambuf_ref<Allocator>(b), delim);-}+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read_until(s, basic_streambuf_ref<Allocator>(b),+        delim, ASIO_MOVE_CAST(ReadToken)(token))));  /// Start an asynchronous operation to read data into a streambuf until it /// contains a specified delimiter.@@ -2279,7 +2268,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -2329,27 +2318,20 @@  */ template <typename AsyncReadStream, typename Allocator,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,     asio::basic_streambuf<Allocator>& b,     ASIO_STRING_VIEW_PARAM delim,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>())-  -> decltype(-    async_initiate<ReadToken,-      void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_delim_string_v1<-          AsyncReadStream>>(),-        token, basic_streambuf_ref<Allocator>(b),-        static_cast<std::string>(delim)))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_delim_string_v1<AsyncReadStream>(s),-      token, basic_streambuf_ref<Allocator>(b),-      static_cast<std::string>(delim));-}+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read_until(s, basic_streambuf_ref<Allocator>(b),+        delim, ASIO_MOVE_CAST(ReadToken)(token))));  #if defined(ASIO_HAS_BOOST_REGEX) \   || defined(GENERATING_DOCUMENTATION)@@ -2403,7 +2385,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -2452,26 +2434,21 @@  * if they are also supported by the @c AsyncReadStream type's  * @c async_read_some operation.  */-template <typename AsyncReadStream, typename Allocator, typename Traits,+template <typename AsyncReadStream, typename Allocator,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,-    asio::basic_streambuf<Allocator>& b,-    const boost::basic_regex<char, Traits>& expr,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>())-  -> decltype(-    async_initiate<ReadToken,-      void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_expr_v1<AsyncReadStream>>(),-        token, basic_streambuf_ref<Allocator>(b), expr))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_expr_v1<AsyncReadStream>(s),-      token, basic_streambuf_ref<Allocator>(b), expr);-}+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    asio::basic_streambuf<Allocator>& b, const boost::regex& expr,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read_until(s, basic_streambuf_ref<Allocator>(b),+        expr, ASIO_MOVE_CAST(ReadToken)(token))));  #endif // defined(ASIO_HAS_BOOST_REGEX)        // || defined(GENERATING_DOCUMENTATION)@@ -2536,7 +2513,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @note After a successful async_read_until operation, the streambuf may  * contain additional data beyond that which matched the function object. An@@ -2618,24 +2595,21 @@  */ template <typename AsyncReadStream, typename Allocator, typename MatchCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,-    asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<is_match_condition<MatchCondition>::value> = 0)-  -> decltype(-    async_initiate<ReadToken,-      void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_match_v1<AsyncReadStream>>(),-        token, basic_streambuf_ref<Allocator>(b), match_condition))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_match_v1<AsyncReadStream>(s),-      token, basic_streambuf_ref<Allocator>(b), match_condition);-}+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s,+    asio::basic_streambuf<Allocator>& b,+    MatchCondition match_condition,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<is_match_condition<MatchCondition>::value>::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_read_until(s, basic_streambuf_ref<Allocator>(b),+        match_condition, ASIO_MOVE_CAST(ReadToken)(token))));  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -2690,7 +2664,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -2741,26 +2715,23 @@  */ template <typename AsyncReadStream, typename DynamicBuffer_v2,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,-    DynamicBuffer_v2 buffers, char delim,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers, char delim,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_delim_v2<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v2&&>(buffers), delim))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_delim_v2<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v2&&>(buffers), delim);-}+        declval<detail::initiate_async_read_until_delim_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim)));  /// Start an asynchronous operation to read data into a dynamic buffer sequence /// until it contains a specified delimiter.@@ -2810,7 +2781,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -2861,29 +2832,26 @@  */ template <typename AsyncReadStream, typename DynamicBuffer_v2,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,     ASIO_STRING_VIEW_PARAM delim,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(         declval<detail::initiate_async_read_until_delim_string_v2<-          AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v2&&>(buffers),-        static_cast<std::string>(delim)))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_delim_string_v2<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v2&&>(buffers),-      static_cast<std::string>(delim));-}+          AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        static_cast<std::string>(delim))));  #if !defined(ASIO_NO_EXTENSIONS) #if defined(ASIO_HAS_BOOST_REGEX) \@@ -2941,7 +2909,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -2991,28 +2959,26 @@  * if they are also supported by the @c AsyncReadStream type's  * @c async_read_some operation.  */-template <typename AsyncReadStream, typename DynamicBuffer_v2, typename Traits,+template <typename AsyncReadStream, typename DynamicBuffer_v2,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,-    const boost::basic_regex<char, Traits>& expr,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+    const boost::regex& expr,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_expr_v2<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v2&&>(buffers), expr))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_expr_v2<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v2&&>(buffers), expr);-}+        declval<detail::initiate_async_read_until_expr_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr)));  #endif // defined(ASIO_HAS_BOOST_REGEX)        // || defined(GENERATING_DOCUMENTATION)@@ -3080,7 +3046,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @note After a successful async_read_until operation, the dynamic buffer  * sequence may contain additional data beyond that which matched the function@@ -3099,7 +3065,7 @@  * To asynchronously read data into a @c std::string until whitespace is  * encountered:  * @code typedef asio::buffers_iterator<- *     asio::const_buffer> iterator;+ *     asio::const_buffers_1> iterator;  *  * std::pair<iterator, bool>  * match_whitespace(iterator begin, iterator end)@@ -3164,30 +3130,28 @@ template <typename AsyncReadStream,     typename DynamicBuffer_v2, typename MatchCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) ReadToken = default_completion_token_t<-        typename AsyncReadStream::executor_type>>-inline auto async_read_until(AsyncReadStream& s,-    DynamicBuffer_v2 buffers, MatchCondition match_condition,-    ReadToken&& token = default_completion_token_t<-      typename AsyncReadStream::executor_type>(),-    constraint_t<+      std::size_t)) ReadToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncReadStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+    void (asio::error_code, std::size_t))+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,+    MatchCondition match_condition,+    ASIO_MOVE_ARG(ReadToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncReadStream::executor_type),+    typename constraint<       is_match_condition<MatchCondition>::value-    > = 0,-    constraint_t<+    >::type = 0,+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_read_until_match_v2<AsyncReadStream>>(),-        token, static_cast<DynamicBuffer_v2&&>(buffers), match_condition))-{-  return async_initiate<ReadToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_read_until_match_v2<AsyncReadStream>(s),-      token, static_cast<DynamicBuffer_v2&&>(buffers),-      match_condition);-}+        declval<detail::initiate_async_read_until_match_v2<AsyncReadStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        match_condition)));  #endif // !defined(ASIO_NO_EXTENSIONS) 
link/modules/asio-standalone/asio/include/asio/readable_pipe.hpp view
@@ -2,7 +2,7 @@ // readable_pipe.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/recycling_allocator.hpp view
@@ -2,7 +2,7 @@ // recycling_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -44,27 +44,27 @@   };    /// Default constructor.-  constexpr recycling_allocator() noexcept+  ASIO_CONSTEXPR recycling_allocator() ASIO_NOEXCEPT   {   }    /// Converting constructor.   template <typename U>-  constexpr recycling_allocator(-      const recycling_allocator<U>&) noexcept+  ASIO_CONSTEXPR recycling_allocator(+      const recycling_allocator<U>&) ASIO_NOEXCEPT   {   }    /// Equality operator. Always returns true.-  constexpr bool operator==(-      const recycling_allocator&) const noexcept+  ASIO_CONSTEXPR bool operator==(+      const recycling_allocator&) const ASIO_NOEXCEPT   {     return true;   }    /// Inequality operator. Always returns false.-  constexpr bool operator!=(-      const recycling_allocator&) const noexcept+  ASIO_CONSTEXPR bool operator!=(+      const recycling_allocator&) const ASIO_NOEXCEPT   {     return false;   }@@ -105,27 +105,27 @@   };    /// Default constructor.-  constexpr recycling_allocator() noexcept+  ASIO_CONSTEXPR recycling_allocator() ASIO_NOEXCEPT   {   }    /// Converting constructor.   template <typename U>-  constexpr recycling_allocator(-      const recycling_allocator<U>&) noexcept+  ASIO_CONSTEXPR recycling_allocator(+      const recycling_allocator<U>&) ASIO_NOEXCEPT   {   }    /// Equality operator. Always returns true.-  constexpr bool operator==(-      const recycling_allocator&) const noexcept+  ASIO_CONSTEXPR bool operator==(+      const recycling_allocator&) const ASIO_NOEXCEPT   {     return true;   }    /// Inequality operator. Always returns false.-  constexpr bool operator!=(-      const recycling_allocator&) const noexcept+  ASIO_CONSTEXPR bool operator!=(+      const recycling_allocator&) const ASIO_NOEXCEPT   {     return false;   }
link/modules/asio-standalone/asio/include/asio/redirect_error.hpp view
@@ -2,7 +2,7 @@ // redirect_error.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -33,10 +33,11 @@ class redirect_error_t { public:-  /// Constructor.+  /// Constructor.    template <typename T>-  redirect_error_t(T&& completion_token, asio::error_code& ec)-    : token_(static_cast<T&&>(completion_token)),+  redirect_error_t(ASIO_MOVE_ARG(T) completion_token,+      asio::error_code& ec)+    : token_(ASIO_MOVE_CAST(T)(completion_token)),       ec_(ec)   {   }@@ -46,53 +47,14 @@   asio::error_code& ec_; }; -/// A function object type that adapts a @ref completion_token to capture-/// error_code values to a variable.-/**- * May also be used directly as a completion token, in which case it adapts the- * asynchronous operation's default completion token (or asio::deferred- * if no default is available).- */-class partial_redirect_error-{-public:-  /// Constructor that specifies the variable used to capture error_code values.-  explicit partial_redirect_error(asio::error_code& ec)-    : ec_(ec)-  {-  }--  /// Adapt a @ref completion_token to specify that the completion handler-  /// should capture error_code values to a variable.-  template <typename CompletionToken>-  ASIO_NODISCARD inline-  constexpr redirect_error_t<decay_t<CompletionToken>>-  operator()(CompletionToken&& completion_token) const-  {-    return redirect_error_t<decay_t<CompletionToken>>(-        static_cast<CompletionToken&&>(completion_token), ec_);-  }--//private:-  asio::error_code& ec_;-};--/// Create a partial completion token adapter that captures error_code values-/// to a variable.-ASIO_NODISCARD inline partial_redirect_error-redirect_error(asio::error_code& ec)-{-  return partial_redirect_error(ec);-}- /// Adapt a @ref completion_token to capture error_code values to a variable. template <typename CompletionToken>-ASIO_NODISCARD inline redirect_error_t<decay_t<CompletionToken>>-redirect_error(CompletionToken&& completion_token,+inline redirect_error_t<typename decay<CompletionToken>::type> redirect_error(+    ASIO_MOVE_ARG(CompletionToken) completion_token,     asio::error_code& ec) {-  return redirect_error_t<decay_t<CompletionToken>>(-      static_cast<CompletionToken&&>(completion_token), ec);+  return redirect_error_t<typename decay<CompletionToken>::type>(+      ASIO_MOVE_CAST(CompletionToken)(completion_token), ec); }  } // namespace asio
link/modules/asio-standalone/asio/include/asio/registered_buffer.hpp view
@@ -2,7 +2,7 @@ // registered_buffer.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -37,28 +37,28 @@   typedef int native_handle_type;    /// Default constructor creates an invalid registered buffer identifier.-  registered_buffer_id() noexcept+  registered_buffer_id() ASIO_NOEXCEPT     : scope_(0),       index_(-1)   {   }    /// Get the native buffer identifier type.-  native_handle_type native_handle() const noexcept+  native_handle_type native_handle() const ASIO_NOEXCEPT   {     return index_;   }    /// Compare two IDs for equality.   friend bool operator==(const registered_buffer_id& lhs,-      const registered_buffer_id& rhs) noexcept+      const registered_buffer_id& rhs) ASIO_NOEXCEPT   {     return lhs.scope_ == rhs.scope_ && lhs.index_ == rhs.index_;   }    /// Compare two IDs for equality.   friend bool operator!=(const registered_buffer_id& lhs,-      const registered_buffer_id& rhs) noexcept+      const registered_buffer_id& rhs) ASIO_NOEXCEPT   {     return lhs.scope_ != rhs.scope_ || lhs.index_ != rhs.index_;   }@@ -67,7 +67,7 @@   friend class detail::buffer_registration_base;    // Hidden constructor used by buffer registration.-  registered_buffer_id(const void* scope, int index) noexcept+  registered_buffer_id(const void* scope, int index) ASIO_NOEXCEPT     : scope_(scope),       index_(index)   {@@ -78,21 +78,27 @@ };  /// Holds a registered buffer over modifiable data.-/**+/**   * Satisfies the @c MutableBufferSequence type requirements.  */ class mutable_registered_buffer { public:+#if !defined(ASIO_HAS_DECLTYPE) \+  && !defined(GENERATING_DOCUMENTATION)+  typedef mutable_buffer value_type;+#endif // !defined(ASIO_HAS_DECLTYPE)+       //   && !defined(GENERATING_DOCUMENTATION)+   /// Default constructor creates an invalid registered buffer.-  mutable_registered_buffer() noexcept+  mutable_registered_buffer() ASIO_NOEXCEPT     : buffer_(),       id_()   {   }    /// Get the underlying mutable buffer.-  const mutable_buffer& buffer() const noexcept+  const mutable_buffer& buffer() const ASIO_NOEXCEPT   {     return buffer_;   }@@ -101,7 +107,7 @@   /**    * @returns <tt>buffer().data()</tt>.    */-  void* data() const noexcept+  void* data() const ASIO_NOEXCEPT   {     return buffer_.data();   }@@ -110,19 +116,19 @@   /**    * @returns <tt>buffer().size()</tt>.    */-  std::size_t size() const noexcept+  std::size_t size() const ASIO_NOEXCEPT   {     return buffer_.size();   }    /// Get the registered buffer identifier.-  const registered_buffer_id& id() const noexcept+  const registered_buffer_id& id() const ASIO_NOEXCEPT   {     return id_;   }    /// Move the start of the buffer by the specified number of bytes.-  mutable_registered_buffer& operator+=(std::size_t n) noexcept+  mutable_registered_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT   {     buffer_ += n;     return *this;@@ -133,7 +139,7 @@    // Hidden constructor used by buffer registration and operators.   mutable_registered_buffer(const mutable_buffer& b,-      const registered_buffer_id& i) noexcept+      const registered_buffer_id& i) ASIO_NOEXCEPT     : buffer_(b),       id_(i)   {@@ -141,7 +147,7 @@  #if !defined(GENERATING_DOCUMENTATION)   friend mutable_registered_buffer buffer(-      const mutable_registered_buffer& b, std::size_t n) noexcept;+      const mutable_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT; #endif // !defined(GENERATING_DOCUMENTATION)    mutable_buffer buffer_;@@ -149,14 +155,20 @@ };  /// Holds a registered buffer over non-modifiable data.-/**+/**   * Satisfies the @c ConstBufferSequence type requirements.  */ class const_registered_buffer { public:+#if !defined(ASIO_HAS_DECLTYPE) \+  && !defined(GENERATING_DOCUMENTATION)+  typedef const_buffer value_type;+#endif // !defined(ASIO_HAS_DECLTYPE)+       //   && !defined(GENERATING_DOCUMENTATION)+   /// Default constructor creates an invalid registered buffer.-  const_registered_buffer() noexcept+  const_registered_buffer() ASIO_NOEXCEPT     : buffer_(),       id_()   {@@ -164,14 +176,14 @@    /// Construct a non-modifiable buffer from a modifiable one.   const_registered_buffer(-      const mutable_registered_buffer& b) noexcept+      const mutable_registered_buffer& b) ASIO_NOEXCEPT     : buffer_(b.buffer()),       id_(b.id())   {   }    /// Get the underlying constant buffer.-  const const_buffer& buffer() const noexcept+  const const_buffer& buffer() const ASIO_NOEXCEPT   {     return buffer_;   }@@ -180,7 +192,7 @@   /**    * @returns <tt>buffer().data()</tt>.    */-  const void* data() const noexcept+  const void* data() const ASIO_NOEXCEPT   {     return buffer_.data();   }@@ -189,19 +201,19 @@   /**    * @returns <tt>buffer().size()</tt>.    */-  std::size_t size() const noexcept+  std::size_t size() const ASIO_NOEXCEPT   {     return buffer_.size();   }    /// Get the registered buffer identifier.-  const registered_buffer_id& id() const noexcept+  const registered_buffer_id& id() const ASIO_NOEXCEPT   {     return id_;   }    /// Move the start of the buffer by the specified number of bytes.-  const_registered_buffer& operator+=(std::size_t n) noexcept+  const_registered_buffer& operator+=(std::size_t n) ASIO_NOEXCEPT   {     buffer_ += n;     return *this;@@ -210,7 +222,7 @@ private:   // Hidden constructor used by operators.   const_registered_buffer(const const_buffer& b,-      const registered_buffer_id& i) noexcept+      const registered_buffer_id& i) ASIO_NOEXCEPT     : buffer_(b),       id_(i)   {@@ -218,7 +230,7 @@  #if !defined(GENERATING_DOCUMENTATION)   friend const_registered_buffer buffer(-      const const_registered_buffer& b, std::size_t n) noexcept;+      const const_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT; #endif // !defined(GENERATING_DOCUMENTATION)    const_buffer buffer_;@@ -229,14 +241,14 @@  /// Get an iterator to the first element in a buffer sequence. inline const mutable_buffer* buffer_sequence_begin(-    const mutable_registered_buffer& b) noexcept+    const mutable_registered_buffer& b) ASIO_NOEXCEPT {   return &b.buffer(); }  /// Get an iterator to the first element in a buffer sequence. inline const const_buffer* buffer_sequence_begin(-    const const_registered_buffer& b) noexcept+    const const_registered_buffer& b) ASIO_NOEXCEPT {   return &b.buffer(); }@@ -246,14 +258,14 @@  /// Get an iterator to one past the end element in a buffer sequence. inline const mutable_buffer* buffer_sequence_end(-    const mutable_registered_buffer& b) noexcept+    const mutable_registered_buffer& b) ASIO_NOEXCEPT {   return &b.buffer() + 1; }  /// Get an iterator to one past the end element in a buffer sequence. inline const const_buffer* buffer_sequence_end(-    const const_registered_buffer& b) noexcept+    const const_registered_buffer& b) ASIO_NOEXCEPT {   return &b.buffer() + 1; }@@ -263,28 +275,28 @@  /// Obtain a buffer representing the entire registered buffer. inline mutable_registered_buffer buffer(-    const mutable_registered_buffer& b) noexcept+    const mutable_registered_buffer& b) ASIO_NOEXCEPT {   return b; }  /// Obtain a buffer representing the entire registered buffer. inline const_registered_buffer buffer(-    const const_registered_buffer& b) noexcept+    const const_registered_buffer& b) ASIO_NOEXCEPT {   return b; }  /// Obtain a buffer representing part of a registered buffer. inline mutable_registered_buffer buffer(-    const mutable_registered_buffer& b, std::size_t n) noexcept+    const mutable_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT {   return mutable_registered_buffer(buffer(b.buffer_, n), b.id_); }  /// Obtain a buffer representing part of a registered buffer. inline const_registered_buffer buffer(-    const const_registered_buffer& b, std::size_t n) noexcept+    const const_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT {   return const_registered_buffer(buffer(b.buffer_, n), b.id_); }@@ -297,7 +309,7 @@  * @relates mutable_registered_buffer  */ inline mutable_registered_buffer operator+(-    const mutable_registered_buffer& b, std::size_t n) noexcept+    const mutable_registered_buffer& b, std::size_t n) ASIO_NOEXCEPT {   mutable_registered_buffer tmp(b);   tmp += n;@@ -309,7 +321,7 @@  * @relates mutable_registered_buffer  */ inline mutable_registered_buffer operator+(std::size_t n,-    const mutable_registered_buffer& b) noexcept+    const mutable_registered_buffer& b) ASIO_NOEXCEPT {   return b + n; }@@ -320,7 +332,7 @@  * @relates const_registered_buffer  */ inline const_registered_buffer operator+(const const_registered_buffer& b,-    std::size_t n) noexcept+    std::size_t n) ASIO_NOEXCEPT {   const_registered_buffer tmp(b);   tmp += n;@@ -332,7 +344,7 @@  * @relates const_registered_buffer  */ inline const_registered_buffer operator+(std::size_t n,-    const const_registered_buffer& b) noexcept+    const const_registered_buffer& b) ASIO_NOEXCEPT {   return b + n; }
link/modules/asio-standalone/asio/include/asio/require.hpp view
@@ -2,7 +2,7 @@ // require.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -107,10 +107,10 @@  namespace asio_require_fn { -using asio::conditional_t;-using asio::decay_t;+using asio::conditional;+using asio::decay; using asio::declval;-using asio::enable_if_t;+using asio::enable_if; using asio::is_applicable_property; using asio::traits::require_free; using asio::traits::require_member;@@ -132,95 +132,99 @@     typename = void, typename = void, typename = void, typename = void> struct call_traits {-  static constexpr overload_type overload = ill_formed;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_requirable-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_requirable+  >::type,+  typename enable_if<     static_require<T, Property>::is_valid-  >>+  >::type> {-  static constexpr overload_type overload = identity;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); -  typedef T&& result_type;+#if defined(ASIO_HAS_MOVE)+  typedef ASIO_MOVE_ARG(T) result_type;+#else // defined(ASIO_HAS_MOVE)+  typedef ASIO_MOVE_ARG(typename decay<T>::type) result_type;+#endif // defined(ASIO_HAS_MOVE) };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_requirable-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_requirable+  >::type,+  typename enable_if<     !static_require<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     require_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >> :+  >::type> :   require_member<typename Impl::template proxy<T>::type, Property> {-  static constexpr overload_type overload = call_member;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_requirable-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_requirable+  >::type,+  typename enable_if<     !static_require<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !require_member<typename Impl::template proxy<T>::type, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     require_free<T, Property>::is_valid-  >> :+  >::type> :   require_free<T, Property> {-  static constexpr overload_type overload = call_free;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); };  template <typename Impl, typename T, typename P0, typename P1> struct call_traits<Impl, T, void(P0, P1),-  enable_if_t<+  typename enable_if<     call_traits<Impl, T, void(P0)>::overload != ill_formed-  >,-  enable_if_t<+  >::type,+  typename enable_if<     call_traits<       Impl,       typename call_traits<Impl, T, void(P0)>::result_type,       void(P1)     >::overload != ill_formed-  >>+  >::type> {-  static constexpr overload_type overload = two_props;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = two_props); -  static constexpr bool is_noexcept =+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =     (       call_traits<Impl, T, void(P0)>::is_noexcept       &&@@ -229,51 +233,51 @@         typename call_traits<Impl, T, void(P0)>::result_type,         void(P1)       >::is_noexcept-    );+    )); -  typedef decay_t<+  typedef typename decay<     typename call_traits<       Impl,       typename call_traits<Impl, T, void(P0)>::result_type,       void(P1)     >::result_type-  > result_type;+  >::type result_type; };  template <typename Impl, typename T, typename P0,-    typename P1, typename... PN>-struct call_traits<Impl, T, void(P0, P1, PN...),-  enable_if_t<+    typename P1, typename ASIO_ELLIPSIS PN>+struct call_traits<Impl, T, void(P0, P1, PN ASIO_ELLIPSIS),+  typename enable_if<     call_traits<Impl, T, void(P0)>::overload != ill_formed-  >,-  enable_if_t<+  >::type,+  typename enable_if<     call_traits<       Impl,       typename call_traits<Impl, T, void(P0)>::result_type,-      void(P1, PN...)+      void(P1, PN ASIO_ELLIPSIS)     >::overload != ill_formed-  >>+  >::type> {-  static constexpr overload_type overload = n_props;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = n_props); -  static constexpr bool is_noexcept =+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =     (       call_traits<Impl, T, void(P0)>::is_noexcept       &&       call_traits<         Impl,         typename call_traits<Impl, T, void(P0)>::result_type,-        void(P1, PN...)+        void(P1, PN ASIO_ELLIPSIS)       >::is_noexcept-    );+    )); -  typedef decay_t<+  typedef typename decay<     typename call_traits<       Impl,       typename call_traits<Impl, T, void(P0)>::result_type,-      void(P1, PN...)+      void(P1, PN ASIO_ELLIPSIS)     >::result_type-  > result_type;+  >::type result_type; };  struct impl@@ -285,14 +289,16 @@     struct type     {       template <typename P>-      auto require(P&& p)+      auto require(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().require(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().require(static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().require(+            ASIO_MOVE_CAST(P)(p))         );     }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -301,63 +307,91 @@   };    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == identity,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&&) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property)) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return static_cast<T&&>(t);+    return ASIO_MOVE_CAST(T)(t);   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_member,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return static_cast<T&&>(t).require(static_cast<Property&&>(p));+    return ASIO_MOVE_CAST(T)(t).require(+        ASIO_MOVE_CAST(Property)(p));   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_free,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return require(static_cast<T&&>(t), static_cast<Property&&>(p));+    return require(+        ASIO_MOVE_CAST(T)(t),+        ASIO_MOVE_CAST(Property)(p));   }    template <typename T, typename P0, typename P1>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(P0, P1)>::overload == two_props,     typename call_traits<impl, T, void(P0, P1)>::result_type-  >-  operator()(T&& t, P0&& p0, P1&& p1) const-    noexcept(call_traits<impl, T, void(P0, P1)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(P0) p0,+      ASIO_MOVE_ARG(P1) p1) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(P0, P1)>::is_noexcept))   {     return (*this)(-        (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),-        static_cast<P1&&>(p1));+        (*this)(+          ASIO_MOVE_CAST(T)(t),+          ASIO_MOVE_CAST(P0)(p0)),+        ASIO_MOVE_CAST(P1)(p1));   }    template <typename T, typename P0, typename P1,-    typename... PN>-  ASIO_NODISCARD constexpr enable_if_t<-    call_traits<impl, T, void(P0, P1, PN...)>::overload == n_props,-    typename call_traits<impl, T, void(P0, P1, PN...)>::result_type-  >-  operator()(T&& t, P0&& p0, P1&& p1, PN&&... pn) const-    noexcept(call_traits<impl, T, void(P0, P1, PN...)>::is_noexcept)+    typename ASIO_ELLIPSIS PN>+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<+    call_traits<impl, T,+      void(P0, P1, PN ASIO_ELLIPSIS)>::overload == n_props,+    typename call_traits<impl, T,+      void(P0, P1, PN ASIO_ELLIPSIS)>::result_type+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(P0) p0,+      ASIO_MOVE_ARG(P1) p1,+      ASIO_MOVE_ARG(PN) ASIO_ELLIPSIS pn) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(P0, P1, PN ASIO_ELLIPSIS)>::is_noexcept))   {     return (*this)(-        (*this)(static_cast<T&&>(t), static_cast<P0&&>(p0)),-        static_cast<P1&&>(p1), static_cast<PN&&>(pn)...);+        (*this)(+          ASIO_MOVE_CAST(T)(t),+          ASIO_MOVE_CAST(P0)(p0)),+        ASIO_MOVE_CAST(P1)(p1),+        ASIO_MOVE_CAST(PN)(pn) ASIO_ELLIPSIS);   } }; @@ -374,13 +408,15 @@ namespace asio { namespace { -static constexpr const asio_require_fn::impl&+static ASIO_CONSTEXPR const asio_require_fn::impl&   require = asio_require_fn::static_instance<>::instance;  } // namespace  typedef asio_require_fn::impl require_t; +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct can_require :   integral_constant<bool,@@ -390,14 +426,51 @@ { }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+    typename P1 = void, typename P2 = void>+struct can_require :+  integral_constant<bool,+    asio_require_fn::call_traits<require_t, T, void(P0, P1, P2)>::overload+      != asio_require_fn::ill_formed>+{+};++template <typename T, typename P0, typename P1>+struct can_require<T, P0, P1> :+  integral_constant<bool,+    asio_require_fn::call_traits<require_t, T, void(P0, P1)>::overload+      != asio_require_fn::ill_formed>+{+};++template <typename T, typename P0>+struct can_require<T, P0> :+  integral_constant<bool,+    asio_require_fn::call_traits<require_t, T, void(P0)>::overload+      != asio_require_fn::ill_formed>+{+};++template <typename T>+struct can_require<T> :+  false_type+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) -template <typename T, typename... Properties>+template <typename T, typename ASIO_ELLIPSIS Properties> constexpr bool can_require_v-  = can_require<T, Properties...>::value;+  = can_require<T, Properties ASIO_ELLIPSIS>::value;  #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct is_nothrow_require :   integral_constant<bool,@@ -406,14 +479,51 @@ { }; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+    typename P1 = void, typename P2 = void>+struct is_nothrow_require :+  integral_constant<bool,+    asio_require_fn::call_traits<+      require_t, T, void(P0, P1, P2)>::is_noexcept>+{+};++template <typename T, typename P0, typename P1>+struct is_nothrow_require<T, P0, P1> :+  integral_constant<bool,+    asio_require_fn::call_traits<+      require_t, T, void(P0, P1)>::is_noexcept>+{+};++template <typename T, typename P0>+struct is_nothrow_require<T, P0> :+  integral_constant<bool,+    asio_require_fn::call_traits<+      require_t, T, void(P0)>::is_noexcept>+{+};++template <typename T>+struct is_nothrow_require<T> :+  false_type+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #if defined(ASIO_HAS_VARIABLE_TEMPLATES) -template <typename T, typename... Properties>+template <typename T, typename ASIO_ELLIPSIS Properties> constexpr bool is_nothrow_require_v-  = is_nothrow_require<T, Properties...>::value;+  = is_nothrow_require<T, Properties ASIO_ELLIPSIS>::value;  #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename T, typename... Properties> struct require_result {@@ -421,8 +531,36 @@       require_t, T, void(Properties...)>::result_type type; }; -template <typename T, typename... Properties>-using require_result_t = typename require_result<T, Properties...>::type;+#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename P0 = void,+    typename P1 = void, typename P2 = void>+struct require_result+{+  typedef typename asio_require_fn::call_traits<+      require_t, T, void(P0, P1, P2)>::result_type type;+};++template <typename T, typename P0, typename P1>+struct require_result<T, P0, P1>+{+  typedef typename asio_require_fn::call_traits<+      require_t, T, void(P0, P1)>::result_type type;+};++template <typename T, typename P0>+struct require_result<T, P0>+{+  typedef typename asio_require_fn::call_traits<+      require_t, T, void(P0)>::result_type type;+};++template <typename T>+struct require_result<T>+{+};++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/require_concept.hpp view
@@ -2,7 +2,7 @@ // require_concept.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -107,10 +107,10 @@  namespace asio_require_concept_fn { -using asio::conditional_t;-using asio::decay_t;+using asio::conditional;+using asio::decay; using asio::declval;-using asio::enable_if_t;+using asio::enable_if; using asio::is_applicable_property; using asio::traits::require_concept_free; using asio::traits::require_concept_member;@@ -130,85 +130,85 @@     typename = void, typename = void, typename = void, typename = void> struct call_traits {-  static constexpr overload_type overload = ill_formed;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = ill_formed);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_requirable_concept-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_requirable_concept+  >::type,+  typename enable_if<     static_require_concept<T, Property>::is_valid-  >>+  >::type> {-  static constexpr overload_type overload = identity;-  static constexpr bool is_noexcept = true;-  typedef T&& result_type;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = identity);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef ASIO_MOVE_ARG(T) result_type; };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_requirable_concept-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_requirable_concept+  >::type,+  typename enable_if<     !static_require_concept<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     require_concept_member<       typename Impl::template proxy<T>::type,       Property     >::is_valid-  >> :+  >::type> :   require_concept_member<     typename Impl::template proxy<T>::type,     Property   > {-  static constexpr overload_type overload = call_member;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_member); };  template <typename Impl, typename T, typename Property> struct call_traits<Impl, T, void(Property),-  enable_if_t<+  typename enable_if<     is_applicable_property<-      decay_t<T>,-      decay_t<Property>+      typename decay<T>::type,+      typename decay<Property>::type     >::value-  >,-  enable_if_t<-    decay_t<Property>::is_requirable_concept-  >,-  enable_if_t<+  >::type,+  typename enable_if<+    decay<Property>::type::is_requirable_concept+  >::type,+  typename enable_if<     !static_require_concept<T, Property>::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     !require_concept_member<       typename Impl::template proxy<T>::type,       Property     >::is_valid-  >,-  enable_if_t<+  >::type,+  typename enable_if<     require_concept_free<T, Property>::is_valid-  >> :+  >::type> :   require_concept_free<T, Property> {-  static constexpr overload_type overload = call_free;+  ASIO_STATIC_CONSTEXPR(overload_type, overload = call_free); };  struct impl@@ -220,16 +220,16 @@     struct type     {       template <typename P>-      auto require_concept(P&& p)+      auto require_concept(ASIO_MOVE_ARG(P) p)         noexcept(           noexcept(-            declval<conditional_t<true, T, P>>().require_concept(-              static_cast<P&&>(p))+            declval<typename conditional<true, T, P>::type>().require_concept(+              ASIO_MOVE_CAST(P)(p))           )         )         -> decltype(-          declval<conditional_t<true, T, P>>().require_concept(-            static_cast<P&&>(p))+          declval<typename conditional<true, T, P>::type>().require_concept(+            ASIO_MOVE_CAST(P)(p))         );     }; #else // defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)@@ -238,36 +238,48 @@   };    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == identity,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&&) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property)) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return static_cast<T&&>(t);+    return ASIO_MOVE_CAST(T)(t);   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_member,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return static_cast<T&&>(t).require_concept(static_cast<Property&&>(p));+    return ASIO_MOVE_CAST(T)(t).require_concept(+        ASIO_MOVE_CAST(Property)(p));   }    template <typename T, typename Property>-  ASIO_NODISCARD constexpr enable_if_t<+  ASIO_NODISCARD ASIO_CONSTEXPR typename enable_if<     call_traits<impl, T, void(Property)>::overload == call_free,     typename call_traits<impl, T, void(Property)>::result_type-  >-  operator()(T&& t, Property&& p) const-    noexcept(call_traits<impl, T, void(Property)>::is_noexcept)+  >::type+  operator()(+      ASIO_MOVE_ARG(T) t,+      ASIO_MOVE_ARG(Property) p) const+    ASIO_NOEXCEPT_IF((+      call_traits<impl, T, void(Property)>::is_noexcept))   {-    return require_concept(static_cast<T&&>(t), static_cast<Property&&>(p));+    return require_concept(+        ASIO_MOVE_CAST(T)(t),+        ASIO_MOVE_CAST(Property)(p));   } }; @@ -284,7 +296,7 @@ namespace asio { namespace { -static constexpr const asio_require_concept_fn::impl&+static ASIO_CONSTEXPR const asio_require_concept_fn::impl&   require_concept = asio_require_concept_fn::static_instance<>::instance;  } // namespace@@ -303,7 +315,8 @@ #if defined(ASIO_HAS_VARIABLE_TEMPLATES)  template <typename T, typename Property>-constexpr bool can_require_concept_v = can_require_concept<T, Property>::value;+constexpr bool can_require_concept_v+  = can_require_concept<T, Property>::value;  #endif // defined(ASIO_HAS_VARIABLE_TEMPLATES) @@ -329,10 +342,6 @@   typedef typename asio_require_concept_fn::call_traits<       require_concept_t, T, void(Property)>::result_type type; };--template <typename T, typename Property>-using require_concept_result_t =-  typename require_concept_result<T, Property>::type;  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/serial_port.hpp view
@@ -2,7 +2,7 @@ // serial_port.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/serial_port_base.hpp view
@@ -2,7 +2,7 @@ // serial_port_base.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/signal_set.hpp view
@@ -2,7 +2,7 @@ // signal_set.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/signal_set_base.hpp view
@@ -2,7 +2,7 @@ // signal_set_base.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -56,9 +56,7 @@    /// Portability typedef.   typedef flags flags_t;--#else // defined(GENERATING_DOCUMENTATION)-+#elif defined(ASIO_HAS_ENUM_CLASS)   enum class flags : int   {     none = 0,@@ -69,8 +67,21 @@   };    typedef flags flags_t;+#else // defined(ASIO_HAS_ENUM_CLASS)+  struct flags+  {+    enum flags_t+    {+      none = 0,+      restart = ASIO_OS_DEF(SA_RESTART),+      no_child_stop = ASIO_OS_DEF(SA_NOCLDSTOP),+      no_child_wait = ASIO_OS_DEF(SA_NOCLDWAIT),+      dont_care = -1+    };+  }; -#endif // defined(GENERATING_DOCUMENTATION)+  typedef flags::flags_t flags_t;+#endif // defined(ASIO_HAS_ENUM_CLASS)  protected:   /// Protected destructor to prevent deletion through this type.@@ -83,7 +94,7 @@ /**  * @relates signal_set_base::flags  */-inline constexpr bool operator!(signal_set_base::flags_t x)+inline ASIO_CONSTEXPR bool operator!(signal_set_base::flags_t x) {   return static_cast<int>(x) == 0; }@@ -92,7 +103,7 @@ /**  * @relates signal_set_base::flags  */-inline constexpr signal_set_base::flags_t operator&(+inline ASIO_CONSTEXPR signal_set_base::flags_t operator&(     signal_set_base::flags_t x, signal_set_base::flags_t y) {   return static_cast<signal_set_base::flags_t>(@@ -103,7 +114,7 @@ /**  * @relates signal_set_base::flags  */-inline constexpr signal_set_base::flags_t operator|(+inline ASIO_CONSTEXPR signal_set_base::flags_t operator|(     signal_set_base::flags_t x, signal_set_base::flags_t y) {   return static_cast<signal_set_base::flags_t>(@@ -114,7 +125,7 @@ /**  * @relates signal_set_base::flags  */-inline constexpr signal_set_base::flags_t operator^(+inline ASIO_CONSTEXPR signal_set_base::flags_t operator^(     signal_set_base::flags_t x, signal_set_base::flags_t y) {   return static_cast<signal_set_base::flags_t>(@@ -125,7 +136,7 @@ /**  * @relates signal_set_base::flags  */-inline constexpr signal_set_base::flags_t operator~(+inline ASIO_CONSTEXPR signal_set_base::flags_t operator~(     signal_set_base::flags_t x) {   return static_cast<signal_set_base::flags_t>(~static_cast<int>(x));
link/modules/asio-standalone/asio/include/asio/socket_base.hpp view
@@ -2,7 +2,7 @@ // socket_base.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -533,6 +533,17 @@   ASIO_STATIC_CONSTANT(int, max_listen_connections       = ASIO_OS_DEF(SOMAXCONN)); #endif++#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use max_listen_connections.) The maximum length of the queue+  /// of pending incoming connections.+#if defined(GENERATING_DOCUMENTATION)+  static const int max_connections = implementation_defined;+#else+  ASIO_STATIC_CONSTANT(int, max_connections+      = ASIO_OS_DEF(SOMAXCONN));+#endif+#endif // !defined(ASIO_NO_DEPRECATED)  protected:   /// Protected destructor to prevent deletion through this type.
link/modules/asio-standalone/asio/include/asio/spawn.hpp view
@@ -2,7 +2,7 @@ // spawn.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -26,6 +26,10 @@ #include "asio/is_executor.hpp" #include "asio/strand.hpp" +#if defined(ASIO_HAS_BOOST_COROUTINE)+# include <boost/coroutine/all.hpp>+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -72,12 +76,12 @@     suspend_with(&spawned_thread_base::call<F>, &f);   } -  cancellation_slot get_cancellation_slot() const noexcept+  cancellation_slot get_cancellation_slot() const ASIO_NOEXCEPT   {     return cancellation_state_.slot();   } -  cancellation_state get_cancellation_state() const noexcept+  cancellation_state get_cancellation_state() const ASIO_NOEXCEPT   {     return cancellation_state_;   }@@ -101,22 +105,22 @@         parent_cancellation_slot_, in_filter, out_filter);   } -  cancellation_type_t cancelled() const noexcept+  cancellation_type_t cancelled() const ASIO_NOEXCEPT   {     return cancellation_state_.cancelled();   } -  bool has_context_switched() const noexcept+  bool has_context_switched() const ASIO_NOEXCEPT   {     return has_context_switched_;   } -  bool throw_if_cancelled() const noexcept+  bool throw_if_cancelled() const ASIO_NOEXCEPT   {     return throw_if_cancelled_;   } -  void throw_if_cancelled(bool value) noexcept+  void throw_if_cancelled(bool value) ASIO_NOEXCEPT   {     throw_if_cancelled_ = value;   }@@ -131,8 +135,8 @@  private:   // Disallow copying and assignment.-  spawned_thread_base(const spawned_thread_base&) = delete;-  spawned_thread_base& operator=(const spawned_thread_base&) = delete;+  spawned_thread_base(const spawned_thread_base&) ASIO_DELETED;+  spawned_thread_base& operator=(const spawned_thread_base&) ASIO_DELETED;    template <typename F>   static void call(void* f)@@ -141,6 +145,7 @@   } }; + template <typename T> struct spawn_signature {@@ -193,9 +198,9 @@    */   template <typename OtherExecutor>   basic_yield_context(const basic_yield_context<OtherExecutor>& other,-      constraint_t<+      typename constraint<         is_convertible<OtherExecutor, Executor>::value-      > = 0)+      >::type = 0)     : spawned_thread_(other.spawned_thread_),       executor_(other.executor_),       ec_(other.ec_)@@ -203,19 +208,19 @@   }    /// Get the executor associated with the yield context.-  executor_type get_executor() const noexcept+  executor_type get_executor() const ASIO_NOEXCEPT   {     return executor_;   }    /// Get the cancellation slot associated with the coroutine.-  cancellation_slot_type get_cancellation_slot() const noexcept+  cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT   {     return spawned_thread_->get_cancellation_slot();   }    /// Get the cancellation state associated with the coroutine.-  cancellation_state get_cancellation_state() const noexcept+  cancellation_state get_cancellation_state() const ASIO_NOEXCEPT   {     return spawned_thread_->get_cancellation_state();   }@@ -241,10 +246,10 @@    * cancellation state object.    */   template <typename Filter>-  void reset_cancellation_state(Filter&& filter) const+  void reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter) const   {     spawned_thread_->reset_cancellation_state(-        static_cast<Filter&&>(filter));+        ASIO_MOVE_CAST(Filter)(filter));   }    /// Reset the cancellation state associated with the coroutine.@@ -257,30 +262,30 @@    * cancellation state object.    */   template <typename InFilter, typename OutFilter>-  void reset_cancellation_state(InFilter&& in_filter,-      OutFilter&& out_filter) const+  void reset_cancellation_state(ASIO_MOVE_ARG(InFilter) in_filter,+      ASIO_MOVE_ARG(OutFilter) out_filter) const   {     spawned_thread_->reset_cancellation_state(-        static_cast<InFilter&&>(in_filter),-        static_cast<OutFilter&&>(out_filter));+        ASIO_MOVE_CAST(InFilter)(in_filter),+        ASIO_MOVE_CAST(OutFilter)(out_filter));   }    /// Determine whether the current coroutine has been cancelled.-  cancellation_type_t cancelled() const noexcept+  cancellation_type_t cancelled() const ASIO_NOEXCEPT   {     return spawned_thread_->cancelled();   }    /// Determine whether the coroutine throws if trying to suspend when it has   /// been cancelled.-  bool throw_if_cancelled() const noexcept+  bool throw_if_cancelled() const ASIO_NOEXCEPT   {     return spawned_thread_->throw_if_cancelled();   }    /// Set whether the coroutine throws if trying to suspend when it has been   /// cancelled.-  void throw_if_cancelled(bool value) const noexcept+  void throw_if_cancelled(bool value) const ASIO_NOEXCEPT   {     spawned_thread_->throw_if_cancelled(value);   }@@ -397,19 +402,31 @@  */ template <typename Executor, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type)-        CompletionToken = default_completion_token_t<Executor>>-auto spawn(const Executor& ex, F&& function,-    CompletionToken&& token = default_completion_token_t<Executor>(),-    constraint_t<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+        CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const Executor& ex, ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+#if defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<+      !is_same<+        typename decay<CompletionToken>::type,+        boost::coroutines::attributes+      >::value+    >::type = 0,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<Executor>)>>::type>(-          declval<detail::initiate_spawn<Executor>>(),-          token, static_cast<F&&>(function)));+        typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+          declval<detail::initiate_spawn<Executor> >(),+          token, ASIO_MOVE_CAST(F)(function))));  /// Start a new stackful coroutine that executes on a given execution context. /**@@ -442,24 +459,37 @@  */ template <typename ExecutionContext, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<-        typename ExecutionContext::executor_type>)>>::type)-          CompletionToken = default_completion_token_t<-            typename ExecutionContext::executor_type>>-auto spawn(ExecutionContext& ctx, F&& function,-    CompletionToken&& token-      = default_completion_token_t<typename ExecutionContext::executor_type>(),-    constraint_t<+      typename result_of<F(basic_yield_context<+        typename ExecutionContext::executor_type>)>::type>::type)+          CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+            typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<+        typename ExecutionContext::executor_type>)>::type>::type)+spawn(ExecutionContext& ctx, ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename ExecutionContext::executor_type),+#if defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<+      !is_same<+        typename decay<CompletionToken>::type,+        boost::coroutines::attributes+      >::value+    >::type = 0,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<-          typename ExecutionContext::executor_type>)>>::type>(+        typename result_of<F(basic_yield_context<+          typename ExecutionContext::executor_type>)>::type>::type>(             declval<detail::initiate_spawn<-              typename ExecutionContext::executor_type>>(),-            token, static_cast<F&&>(function)));+              typename ExecutionContext::executor_type> >(),+            token, ASIO_MOVE_CAST(F)(function))));  /// Start a new stackful coroutine, inheriting the executor of another. /**@@ -494,19 +524,32 @@  */ template <typename Executor, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type)-        CompletionToken = default_completion_token_t<Executor>>-auto spawn(const basic_yield_context<Executor>& ctx, F&& function,-    CompletionToken&& token = default_completion_token_t<Executor>(),-    constraint_t<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+        CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const basic_yield_context<Executor>& ctx,+    ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+#if defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<+      !is_same<+        typename decay<CompletionToken>::type,+        boost::coroutines::attributes+      >::value+    >::type = 0,+#endif // defined(ASIO_HAS_BOOST_COROUTINE)+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<Executor>)>>::type>(-          declval<detail::initiate_spawn<Executor>>(),-          token, static_cast<F&&>(function)));+        typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+          declval<detail::initiate_spawn<Executor> >(),+          token, ASIO_MOVE_CAST(F)(function))));  #if defined(ASIO_HAS_BOOST_CONTEXT_FIBER) \   || defined(GENERATING_DOCUMENTATION)@@ -546,22 +589,27 @@  */ template <typename Executor, typename StackAllocator, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type)-        CompletionToken = default_completion_token_t<Executor>>-auto spawn(const Executor& ex, allocator_arg_t,-    StackAllocator&& stack_allocator, F&& function,-    CompletionToken&& token = default_completion_token_t<Executor>(),-    constraint_t<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+        CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const Executor& ex, allocator_arg_t,+    ASIO_MOVE_ARG(StackAllocator) stack_allocator,+    ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<Executor>)>>::type>(-          declval<detail::initiate_spawn<Executor>>(),+        typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+          declval<detail::initiate_spawn<Executor> >(),           token, allocator_arg_t(),-          static_cast<StackAllocator&&>(stack_allocator),-          static_cast<F&&>(function)));+          ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+          ASIO_MOVE_CAST(F)(function))));  /// Start a new stackful coroutine that executes on a given execution context. /**@@ -598,27 +646,33 @@  */ template <typename ExecutionContext, typename StackAllocator, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<-        typename ExecutionContext::executor_type>)>>::type)-          CompletionToken = default_completion_token_t<-            typename ExecutionContext::executor_type>>-auto spawn(ExecutionContext& ctx, allocator_arg_t,-    StackAllocator&& stack_allocator, F&& function,-    CompletionToken&& token-      = default_completion_token_t<typename ExecutionContext::executor_type>(),-    constraint_t<+      typename result_of<F(basic_yield_context<+        typename ExecutionContext::executor_type>)>::type>::type)+          CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+            typename ExecutionContext::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<+        typename ExecutionContext::executor_type>)>::type>::type)+spawn(ExecutionContext& ctx, allocator_arg_t,+    ASIO_MOVE_ARG(StackAllocator) stack_allocator,+    ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename ExecutionContext::executor_type),+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<CompletionToken,       typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<-          typename ExecutionContext::executor_type>)>>::type>(+        typename result_of<F(basic_yield_context<+          typename ExecutionContext::executor_type>)>::type>::type>(             declval<detail::initiate_spawn<-              typename ExecutionContext::executor_type>>(),+              typename ExecutionContext::executor_type> >(),             token, allocator_arg_t(),-            static_cast<StackAllocator&&>(stack_allocator),-            static_cast<F&&>(function)));+            ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+            ASIO_MOVE_CAST(F)(function))));  /// Start a new stackful coroutine, inheriting the executor of another. /**@@ -659,24 +713,186 @@  */ template <typename Executor, typename StackAllocator, typename F,     ASIO_COMPLETION_TOKEN_FOR(typename detail::spawn_signature<-      result_of_t<F(basic_yield_context<Executor>)>>::type)-        CompletionToken = default_completion_token_t<Executor>>-auto spawn(const basic_yield_context<Executor>& ctx, allocator_arg_t,-    StackAllocator&& stack_allocator, F&& function,-    CompletionToken&& token = default_completion_token_t<Executor>(),-    constraint_t<-      is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)-  -> decltype(-    async_initiate<CompletionToken,-      typename detail::spawn_signature<-        result_of_t<F(basic_yield_context<Executor>)>>::type>(-          declval<detail::initiate_spawn<Executor>>(),-          token, allocator_arg_t(),-          static_cast<StackAllocator&&>(stack_allocator),-          static_cast<F&&>(function)));+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+        CompletionToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(Executor)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type)+spawn(const basic_yield_context<Executor>& ctx, allocator_arg_t,+    ASIO_MOVE_ARG(StackAllocator) stack_allocator,+    ASIO_MOVE_ARG(F) function,+    ASIO_MOVE_ARG(CompletionToken) token+    ASIO_DEFAULT_COMPLETION_TOKEN(Executor),+  typename constraint<+    is_executor<Executor>::value || execution::is_executor<Executor>::value+  >::type = 0)+ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+  async_initiate<CompletionToken,+    typename detail::spawn_signature<+      typename result_of<F(basic_yield_context<Executor>)>::type>::type>(+        declval<detail::initiate_spawn<Executor> >(),+        token, allocator_arg_t(),+        ASIO_MOVE_CAST(StackAllocator)(stack_allocator),+        ASIO_MOVE_CAST(F)(function))));  #endif // defined(ASIO_HAS_BOOST_CONTEXT_FIBER)+       //   || defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_BOOST_COROUTINE) \+  || defined(GENERATING_DOCUMENTATION)++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine, calling the specified handler when it completes.+/**+ * This function is used to launch a new coroutine.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(basic_yield_context<Executor> yield); @endcode+ * where Executor is the associated executor type of @c Function.+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function>+void spawn(ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes+      = boost::coroutines::attributes());++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine, calling the specified handler when it completes.+/**+ * This function is used to launch a new coroutine.+ *+ * @param handler A handler to be called when the coroutine exits. More+ * importantly, the handler provides an execution context (via the the handler+ * invocation hook) for the coroutine. The handler must have the signature:+ * @code void handler(); @endcode+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(basic_yield_context<Executor> yield); @endcode+ * where Executor is the associated executor type of @c Handler.+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Handler, typename Function>+void spawn(ASIO_MOVE_ARG(Handler) handler,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes+      = boost::coroutines::attributes(),+    typename constraint<+      !is_executor<typename decay<Handler>::type>::value &&+      !execution::is_executor<typename decay<Handler>::type>::value &&+      !is_convertible<Handler&, execution_context&>::value>::type = 0);++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine, inheriting the execution context of another.+/**+ * This function is used to launch a new coroutine.+ *+ * @param ctx Identifies the current coroutine as a parent of the new+ * coroutine. This specifies that the new coroutine should inherit the+ * execution context of the parent. For example, if the parent coroutine is+ * executing in a particular strand, then the new coroutine will execute in the+ * same strand.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(basic_yield_context<Executor> yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Executor, typename Function>+void spawn(basic_yield_context<Executor> ctx,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes+      = boost::coroutines::attributes());++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine that executes on a given executor.+/**+ * This function is used to launch a new coroutine.+ *+ * @param ex Identifies the executor that will run the coroutine. The new+ * coroutine is automatically given its own explicit strand within this+ * executor.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(yield_context yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function, typename Executor>+void spawn(const Executor& ex,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes+      = boost::coroutines::attributes(),+    typename constraint<+      is_executor<Executor>::value || execution::is_executor<Executor>::value+    >::type = 0);++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine that executes on a given strand.+/**+ * This function is used to launch a new coroutine.+ *+ * @param ex Identifies the strand that will run the coroutine.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(yield_context yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function, typename Executor>+void spawn(const strand<Executor>& ex,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes+      = boost::coroutines::attributes());++#if !defined(ASIO_NO_TS_EXECUTORS)++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine that executes in the context of a strand.+/**+ * This function is used to launch a new coroutine.+ *+ * @param s Identifies a strand. By starting multiple coroutines on the same+ * strand, the implementation ensures that none of those coroutines can execute+ * simultaneously.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(yield_context yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function>+void spawn(const asio::io_context::strand& s,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes+      = boost::coroutines::attributes());++#endif // !defined(ASIO_NO_TS_EXECUTORS)++/// (Deprecated: Use overloads with a completion token.) Start a new stackful+/// coroutine that executes on a given execution context.+/**+ * This function is used to launch a new coroutine.+ *+ * @param ctx Identifies the execution context that will run the coroutine. The+ * new coroutine is implicitly given its own strand within this execution+ * context.+ *+ * @param function The coroutine function. The function must have the signature:+ * @code void function(yield_context yield); @endcode+ *+ * @param attributes Boost.Coroutine attributes used to customise the coroutine.+ */+template <typename Function, typename ExecutionContext>+void spawn(ExecutionContext& ctx,+    ASIO_MOVE_ARG(Function) function,+    const boost::coroutines::attributes& attributes+      = boost::coroutines::attributes(),+    typename constraint<is_convertible<+      ExecutionContext&, execution_context&>::value>::type = 0);++#endif // defined(ASIO_HAS_BOOST_COROUTINE)        //   || defined(GENERATING_DOCUMENTATION)  /*@}*/
link/modules/asio-standalone/asio/include/asio/ssl.hpp view
@@ -2,7 +2,7 @@ // ssl.hpp // ~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,7 @@ #include "asio/ssl/context.hpp" #include "asio/ssl/context_base.hpp" #include "asio/ssl/error.hpp"+#include "asio/ssl/rfc2818_verification.hpp" #include "asio/ssl/host_name_verification.hpp" #include "asio/ssl/stream.hpp" #include "asio/ssl/stream_base.hpp"
link/modules/asio-standalone/asio/include/asio/ssl/context.hpp view
@@ -2,7 +2,7 @@ // ssl/context.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -46,6 +46,7 @@   /// Construct to take ownership of a native handle.   ASIO_DECL explicit context(native_handle_type native_handle); +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a context from another.   /**    * This constructor moves an SSL context from one object to another.@@ -71,6 +72,7 @@    * @li As a target for move-assignment.    */   ASIO_DECL context& operator=(context&& other);+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destructor.   ASIO_DECL ~context();
link/modules/asio-standalone/asio/include/asio/ssl/context_base.hpp view
@@ -2,7 +2,7 @@ // ssl/context_base.hpp // ~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ssl/detail/buffered_handshake_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/buffered_handshake_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -29,7 +29,7 @@ class buffered_handshake_op { public:-  static constexpr const char* tracking_name()+  static ASIO_CONSTEXPR const char* tracking_name()   {     return "ssl::stream<>::async_buffered_handshake";   }@@ -56,7 +56,7 @@       const asio::error_code& ec,       const std::size_t& bytes_transferred) const   {-    static_cast<Handler&&>(handler)(ec, bytes_transferred);+    ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred);   }  private:
link/modules/asio-standalone/asio/include/asio/ssl/detail/engine.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/engine.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -61,14 +61,18 @@   // Construct a new engine for an existing native SSL implementation.   ASIO_DECL explicit engine(SSL* ssl_impl); +#if defined(ASIO_HAS_MOVE)   // Move construct from another engine.-  ASIO_DECL engine(engine&& other) noexcept;+  ASIO_DECL engine(engine&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE)    // Destructor.   ASIO_DECL ~engine(); +#if defined(ASIO_HAS_MOVE)   // Move assign from another engine.-  ASIO_DECL engine& operator=(engine&& other) noexcept;+  ASIO_DECL engine& operator=(engine&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE)    // Get the underlying implementation in the native type.   ASIO_DECL SSL* native_handle();
link/modules/asio-standalone/asio/include/asio/ssl/detail/handshake_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/handshake_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -28,7 +28,7 @@ class handshake_op { public:-  static constexpr const char* tracking_name()+  static ASIO_CONSTEXPR const char* tracking_name()   {     return "ssl::stream<>::async_handshake";   }@@ -51,7 +51,7 @@       const asio::error_code& ec,       const std::size_t&) const   {-    static_cast<Handler&&>(handler)(ec);+    ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec);   }  private:
link/modules/asio-standalone/asio/include/asio/ssl/detail/impl/engine.ipp view
@@ -2,7 +2,7 @@ // ssl/detail/impl/engine.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -73,13 +73,15 @@   ::SSL_set_bio(ssl_, int_bio, int_bio); } -engine::engine(engine&& other) noexcept+#if defined(ASIO_HAS_MOVE)+engine::engine(engine&& other) ASIO_NOEXCEPT   : ssl_(other.ssl_),     ext_bio_(other.ext_bio_) {   other.ssl_ = 0;   other.ext_bio_ = 0; }+#endif // defined(ASIO_HAS_MOVE)  engine::~engine() {@@ -96,16 +98,11 @@     ::SSL_free(ssl_); } -engine& engine::operator=(engine&& other) noexcept+#if defined(ASIO_HAS_MOVE)+engine& engine::operator=(engine&& other) ASIO_NOEXCEPT {   if (this != &other)   {-    if (ext_bio_)-      ::BIO_free(ext_bio_);--    if (ssl_)-      ::SSL_free(ssl_);-     ssl_ = other.ssl_;     ext_bio_ = other.ext_bio_;     other.ssl_ = 0;@@ -113,6 +110,7 @@   }   return *this; }+#endif // defined(ASIO_HAS_MOVE)  SSL* engine::native_handle() {
link/modules/asio-standalone/asio/include/asio/ssl/detail/impl/openssl_init.ipp view
@@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com-// Copyright (c) 2005-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -37,7 +37,7 @@   { #if (OPENSSL_VERSION_NUMBER < 0x10100000L)     ::SSL_library_init();-    ::SSL_load_error_strings();+    ::SSL_load_error_strings();             ::OpenSSL_add_all_algorithms();      mutexes_.resize(::CRYPTO_num_locks());@@ -123,7 +123,7 @@ #endif // (OPENSSL_VERSION_NUMBER < 0x10000000L)  #if (OPENSSL_VERSION_NUMBER < 0x10100000L)-  static void openssl_locking_func(int mode, int n,+  static void openssl_locking_func(int mode, int n,      const char* /*file*/, int /*line*/)   {     if (mode & CRYPTO_LOCK)@@ -134,7 +134,7 @@    // Mutexes to be used in locking callbacks.   std::vector<asio::detail::shared_ptr<-        asio::detail::mutex>> mutexes_;+        asio::detail::mutex> > mutexes_; #endif // (OPENSSL_VERSION_NUMBER < 0x10100000L)  #if !defined(SSL_OP_NO_COMPRESSION) \
link/modules/asio-standalone/asio/include/asio/ssl/detail/io.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/io.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -107,10 +107,11 @@       start_(0),       want_(engine::want_nothing),       bytes_transferred_(0),-      handler_(static_cast<Handler&&>(handler))+      handler_(ASIO_MOVE_CAST(Handler)(handler))   {   } +#if defined(ASIO_HAS_MOVE)   io_op(const io_op& other)     : asio::detail::base_from_cancellation_state<Handler>(other),       next_layer_(other.next_layer_),@@ -126,18 +127,20 @@    io_op(io_op&& other)     : asio::detail::base_from_cancellation_state<Handler>(-        static_cast<-          asio::detail::base_from_cancellation_state<Handler>&&>(other)),+        ASIO_MOVE_CAST(+          asio::detail::base_from_cancellation_state<Handler>)(+            other)),       next_layer_(other.next_layer_),       core_(other.core_),-      op_(static_cast<Operation&&>(other.op_)),+      op_(ASIO_MOVE_CAST(Operation)(other.op_)),       start_(other.start_),       want_(other.want_),       ec_(other.ec_),       bytes_transferred_(other.bytes_transferred_),-      handler_(static_cast<Handler&&>(other.handler_))+      handler_(ASIO_MOVE_CAST(Handler)(other.handler_))   {   }+#endif // defined(ASIO_HAS_MOVE)    void operator()(asio::error_code ec,       std::size_t bytes_transferred = ~std::size_t(0), int start = 0)@@ -174,7 +177,7 @@             // Start reading some data from the underlying transport.             next_layer_.async_read_some(                 asio::buffer(core_.input_buffer_),-                static_cast<io_op&&>(*this));+                ASIO_MOVE_CAST(io_op)(*this));           }           else           {@@ -182,7 +185,7 @@                   __FILE__, __LINE__, Operation::tracking_name()));              // Wait until the current read operation completes.-            core_.pending_read_.async_wait(static_cast<io_op&&>(*this));+            core_.pending_read_.async_wait(ASIO_MOVE_CAST(io_op)(*this));           }            // Yield control until asynchronous operation completes. Control@@ -207,7 +210,7 @@             // Start writing all the data to the underlying transport.             asio::async_write(next_layer_,                 core_.engine_.get_output(core_.output_buffer_),-                static_cast<io_op&&>(*this));+                ASIO_MOVE_CAST(io_op)(*this));           }           else           {@@ -215,7 +218,7 @@                   __FILE__, __LINE__, Operation::tracking_name()));              // Wait until the current write operation completes.-            core_.pending_write_.async_wait(static_cast<io_op&&>(*this));+            core_.pending_write_.async_wait(ASIO_MOVE_CAST(io_op)(*this));           }            // Yield control until asynchronous operation completes. Control@@ -236,7 +239,7 @@              next_layer_.async_read_some(                 asio::buffer(core_.input_buffer_, 0),-                static_cast<io_op&&>(*this));+                ASIO_MOVE_CAST(io_op)(*this));              // Yield control until asynchronous operation completes. Control             // resumes at the "default:" label below.@@ -328,6 +331,32 @@ };  template <typename Stream, typename Operation, typename Handler>+inline asio_handler_allocate_is_deprecated+asio_handler_allocate(std::size_t size,+    io_op<Stream, Operation, Handler>* this_handler)+{+#if defined(ASIO_NO_DEPRECATED)+  asio_handler_alloc_helpers::allocate(size, this_handler->handler_);+  return asio_handler_allocate_is_no_longer_used();+#else // defined(ASIO_NO_DEPRECATED)+  return asio_handler_alloc_helpers::allocate(+      size, this_handler->handler_);+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Stream, typename Operation, typename Handler>+inline asio_handler_deallocate_is_deprecated+asio_handler_deallocate(void* pointer, std::size_t size,+    io_op<Stream, Operation, Handler>* this_handler)+{+  asio_handler_alloc_helpers::deallocate(+      pointer, size, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_deallocate_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Stream, typename Operation, typename Handler> inline bool asio_handler_is_continuation(     io_op<Stream, Operation, Handler>* this_handler) {@@ -335,6 +364,32 @@     : asio_handler_cont_helpers::is_continuation(this_handler->handler_); } +template <typename Function, typename Stream,+    typename Operation, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(Function& function,+    io_op<Stream, Operation, Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}++template <typename Function, typename Stream,+    typename Operation, typename Handler>+inline asio_handler_invoke_is_deprecated+asio_handler_invoke(const Function& function,+    io_op<Stream, Operation, Handler>* this_handler)+{+  asio_handler_invoke_helpers::invoke(+      function, this_handler->handler_);+#if defined(ASIO_NO_DEPRECATED)+  return asio_handler_invoke_is_no_longer_used();+#endif // defined(ASIO_NO_DEPRECATED)+}+ template <typename Stream, typename Operation, typename Handler> inline void async_io(Stream& next_layer, stream_core& core,     const Operation& op, Handler& handler)@@ -355,15 +410,19 @@     DefaultCandidate>   : Associator<Handler, DefaultCandidate> {-  static typename Associator<Handler, DefaultCandidate>::type get(-      const ssl::detail::io_op<Stream, Operation, Handler>& h) noexcept+  static typename Associator<Handler, DefaultCandidate>::type+  get(const ssl::detail::io_op<Stream, Operation, Handler>& h)+    ASIO_NOEXCEPT   {     return Associator<Handler, DefaultCandidate>::get(h.handler_);   } -  static auto get(const ssl::detail::io_op<Stream, Operation, Handler>& h,-      const DefaultCandidate& c) noexcept-    -> decltype(Associator<Handler, DefaultCandidate>::get(h.handler_, c))+  static ASIO_AUTO_RETURN_TYPE_PREFIX2(+      typename Associator<Handler, DefaultCandidate>::type)+  get(const ssl::detail::io_op<Stream, Operation, Handler>& h,+      const DefaultCandidate& c) ASIO_NOEXCEPT+    ASIO_AUTO_RETURN_TYPE_SUFFIX((+      Associator<Handler, DefaultCandidate>::get(h.handler_, c)))   {     return Associator<Handler, DefaultCandidate>::get(h.handler_, c);   }
link/modules/asio-standalone/asio/include/asio/ssl/detail/openssl_init.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/openssl_init.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ssl/detail/openssl_types.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/openssl_types.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ssl/detail/password_callback.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/password_callback.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ssl/detail/read_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/read_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -30,7 +30,7 @@ class read_op { public:-  static constexpr const char* tracking_name()+  static ASIO_CONSTEXPR const char* tracking_name()   {     return "ssl::stream<>::async_read_some";   }@@ -56,7 +56,7 @@       const asio::error_code& ec,       const std::size_t& bytes_transferred) const   {-    static_cast<Handler&&>(handler)(ec, bytes_transferred);+    ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred);   }  private:
link/modules/asio-standalone/asio/include/asio/ssl/detail/shutdown_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/shutdown_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -28,7 +28,7 @@ class shutdown_op { public:-  static constexpr const char* tracking_name()+  static ASIO_CONSTEXPR const char* tracking_name()   {     return "ssl::stream<>::async_shutdown";   }@@ -51,11 +51,11 @@       // The engine only generates an eof when the shutdown notification has       // been received from the peer. This indicates that the shutdown has       // completed successfully, and thus need not be passed on to the handler.-      static_cast<Handler&&>(handler)(asio::error_code());+      ASIO_MOVE_OR_LVALUE(Handler)(handler)(asio::error_code());     }     else     {-      static_cast<Handler&&>(handler)(ec);+      ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec);     }   } };
link/modules/asio-standalone/asio/include/asio/ssl/detail/stream_core.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/stream_core.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,9 +17,13 @@  #include "asio/detail/config.hpp" +#if defined(ASIO_HAS_BOOST_DATE_TIME)+# include "asio/deadline_timer.hpp"+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+# include "asio/steady_timer.hpp"+#endif // defined(ASIO_HAS_BOOST_DATE_TIME) #include "asio/ssl/detail/engine.hpp" #include "asio/buffer.hpp"-#include "asio/steady_timer.hpp"  #include "asio/detail/push_options.hpp" @@ -61,20 +65,30 @@     pending_write_.expires_at(neg_infin());   } +#if defined(ASIO_HAS_MOVE)   stream_core(stream_core&& other)-    : engine_(static_cast<engine&&>(other.engine_)),+    : engine_(ASIO_MOVE_CAST(engine)(other.engine_)),+#if defined(ASIO_HAS_BOOST_DATE_TIME)       pending_read_(-         static_cast<asio::steady_timer&&>(+         ASIO_MOVE_CAST(asio::deadline_timer)(            other.pending_read_)),       pending_write_(-         static_cast<asio::steady_timer&&>(+         ASIO_MOVE_CAST(asio::deadline_timer)(            other.pending_write_)),+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+      pending_read_(+         ASIO_MOVE_CAST(asio::steady_timer)(+           other.pending_read_)),+      pending_write_(+         ASIO_MOVE_CAST(asio::steady_timer)(+           other.pending_write_)),+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)       output_buffer_space_(-          static_cast<std::vector<unsigned char>&&>(+          ASIO_MOVE_CAST(std::vector<unsigned char>)(             other.output_buffer_space_)),       output_buffer_(other.output_buffer_),       input_buffer_space_(-          static_cast<std::vector<unsigned char>&&>(+          ASIO_MOVE_CAST(std::vector<unsigned char>)(             other.input_buffer_space_)),       input_buffer_(other.input_buffer_),       input_(other.input_)@@ -83,28 +97,39 @@     other.input_buffer_ = asio::mutable_buffer(0, 0);     other.input_ = asio::const_buffer(0, 0);   }+#endif // defined(ASIO_HAS_MOVE)    ~stream_core()   {   } +#if defined(ASIO_HAS_MOVE)   stream_core& operator=(stream_core&& other)   {     if (this != &other)     {-      engine_ = static_cast<engine&&>(other.engine_);+      engine_ = ASIO_MOVE_CAST(engine)(other.engine_);+#if defined(ASIO_HAS_BOOST_DATE_TIME)       pending_read_ =-        static_cast<asio::steady_timer&&>(+        ASIO_MOVE_CAST(asio::deadline_timer)(           other.pending_read_);       pending_write_ =-        static_cast<asio::steady_timer&&>(+        ASIO_MOVE_CAST(asio::deadline_timer)(           other.pending_write_);+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+      pending_read_ =+        ASIO_MOVE_CAST(asio::steady_timer)(+          other.pending_read_);+      pending_write_ =+        ASIO_MOVE_CAST(asio::steady_timer)(+          other.pending_write_);+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)       output_buffer_space_ =-        static_cast<std::vector<unsigned char>&&>(+        ASIO_MOVE_CAST(std::vector<unsigned char>)(           other.output_buffer_space_);       output_buffer_ = other.output_buffer_;       input_buffer_space_ =-        static_cast<std::vector<unsigned char>&&>(+        ASIO_MOVE_CAST(std::vector<unsigned char>)(           other.input_buffer_space_);       input_buffer_ = other.input_buffer_;       input_ = other.input_;@@ -114,11 +139,38 @@     }     return *this;   }+#endif // defined(ASIO_HAS_MOVE)    // The SSL engine.   engine engine_; +#if defined(ASIO_HAS_BOOST_DATE_TIME)   // Timer used for storing queued read operations.+  asio::deadline_timer pending_read_;++  // Timer used for storing queued write operations.+  asio::deadline_timer pending_write_;++  // Helper function for obtaining a time value that always fires.+  static asio::deadline_timer::time_type neg_infin()+  {+    return boost::posix_time::neg_infin;+  }++  // Helper function for obtaining a time value that never fires.+  static asio::deadline_timer::time_type pos_infin()+  {+    return boost::posix_time::pos_infin;+  }++  // Helper function to get a timer's expiry time.+  static asio::deadline_timer::time_type expiry(+      const asio::deadline_timer& timer)+  {+    return timer.expires_at();+  }+#else // defined(ASIO_HAS_BOOST_DATE_TIME)+  // Timer used for storing queued read operations.   asio::steady_timer pending_read_;    // Timer used for storing queued write operations.@@ -142,6 +194,7 @@   {     return timer.expiry();   }+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)    // Buffer space used to prepare output intended for the transport.   std::vector<unsigned char> output_buffer_space_;
link/modules/asio-standalone/asio/include/asio/ssl/detail/verify_callback.hpp view
@@ -1,8 +1,8 @@ // // ssl/detail/verify_callback.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ssl/detail/write_op.hpp view
@@ -2,7 +2,7 @@ // ssl/detail/write_op.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -30,7 +30,7 @@ class write_op { public:-  static constexpr const char* tracking_name()+  static ASIO_CONSTEXPR const char* tracking_name()   {     return "ssl::stream<>::async_write_some";   }@@ -60,7 +60,7 @@       const asio::error_code& ec,       const std::size_t& bytes_transferred) const   {-    static_cast<Handler&&>(handler)(ec, bytes_transferred);+    ASIO_MOVE_OR_LVALUE(Handler)(handler)(ec, bytes_transferred);   }  private:
link/modules/asio-standalone/asio/include/asio/ssl/error.hpp view
@@ -2,7 +2,7 @@ // ssl/error.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -77,6 +77,7 @@ } // namespace ssl } // namespace asio +#if defined(ASIO_HAS_STD_SYSTEM_ERROR) namespace std {  template<> struct is_error_code_enum<asio::error::ssl_errors>@@ -90,6 +91,7 @@ };  } // namespace std+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)  namespace asio { namespace error {
link/modules/asio-standalone/asio/include/asio/ssl/host_name_verification.hpp view
@@ -2,7 +2,7 @@ // ssl/host_name_verification.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ssl/impl/context.hpp view
@@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com-// Copyright (c) 2005-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ssl/impl/context.ipp view
@@ -3,7 +3,7 @@ // ~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com-// Copyright (c) 2005-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2005-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -269,9 +269,8 @@ #endif // defined(SSL_TXT_TLSV1_2)      // TLS v1.3.-#if ((OPENSSL_VERSION_NUMBER >= 0x10101000L) \-      && !defined(LIBRESSL_VERSION_NUMBER)) \-    || defined(ASIO_USE_WOLFSSL)+#if (OPENSSL_VERSION_NUMBER >= 0x10101000L) \+    && !defined(LIBRESSL_VERSION_NUMBER)   case context::tlsv13:     handle_ = ::SSL_CTX_new(::TLS_method());     if (handle_)@@ -296,18 +295,16 @@       SSL_CTX_set_max_proto_version(handle_, TLS1_3_VERSION);     }     break;-#else // ((OPENSSL_VERSION_NUMBER >= 0x10101000L)-      //     && !defined(LIBRESSL_VERSION_NUMBER))-      //   || defined(ASIO_USE_WOLFSSL)+#else // (OPENSSL_VERSION_NUMBER >= 0x10101000L)+      //   && !defined(LIBRESSL_VERSION_NUMBER)   case context::tlsv13:   case context::tlsv13_client:   case context::tlsv13_server:     asio::detail::throw_error(         asio::error::invalid_argument, "context");     break;-#endif // ((OPENSSL_VERSION_NUMBER >= 0x10101000L)-       //     && !defined(LIBRESSL_VERSION_NUMBER))-       //   || defined(ASIO_USE_WOLFSSL)+#endif // (OPENSSL_VERSION_NUMBER >= 0x10101000L)+       //   && !defined(LIBRESSL_VERSION_NUMBER)      // Any supported SSL/TLS version.   case context::sslv23:@@ -379,6 +376,7 @@   } } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) context::context(context&& other) {   handle_ = other.handle_;@@ -387,11 +385,12 @@  context& context::operator=(context&& other) {-  context tmp(static_cast<context&&>(*this));+  context tmp(ASIO_MOVE_CAST(context)(*this));   handle_ = other.handle_;   other.handle_ = 0;   return *this; }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  context::~context() {@@ -797,7 +796,7 @@         ASIO_SYNC_OP_VOID_RETURN(ec);       }     }-+       result = ::ERR_peek_last_error();     if ((ERR_GET_LIB(result) == ERR_LIB_PEM)         && (ERR_GET_REASON(result) == PEM_R_NO_START_LINE))
link/modules/asio-standalone/asio/include/asio/ssl/impl/error.ipp view
@@ -2,7 +2,7 @@ // ssl/impl/error.ipp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -28,7 +28,7 @@ class ssl_category : public asio::error_category { public:-  const char* name() const noexcept+  const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT   {     return "asio.ssl";   }@@ -88,7 +88,7 @@ class stream_category : public asio::error_category { public:-  const char* name() const noexcept+  const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT   {     return "asio.ssl.stream";   }
link/modules/asio-standalone/asio/include/asio/ssl/impl/host_name_verification.ipp view
@@ -2,7 +2,7 @@ // ssl/impl/host_name_verification.ipp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
+ link/modules/asio-standalone/asio/include/asio/ssl/impl/rfc2818_verification.ipp view
@@ -0,0 +1,164 @@+//+// ssl/impl/rfc2818_verification.ipp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP+#define ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include <cctype>+#include <cstring>+#include "asio/ip/address.hpp"+#include "asio/ssl/rfc2818_verification.hpp"+#include "asio/ssl/detail/openssl_types.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace ssl {++bool rfc2818_verification::operator()(+    bool preverified, verify_context& ctx) const+{+  using namespace std; // For memcmp.++  // Don't bother looking at certificates that have failed pre-verification.+  if (!preverified)+    return false;++  // We're only interested in checking the certificate at the end of the chain.+  int depth = X509_STORE_CTX_get_error_depth(ctx.native_handle());+  if (depth > 0)+    return true;++  // Try converting the host name to an address. If it is an address then we+  // need to look for an IP address in the certificate rather than a host name.+  asio::error_code ec;+  ip::address address = ip::make_address(host_, ec);+  bool is_address = !ec;++  X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());++  // Go through the alternate names in the certificate looking for matching DNS+  // or IP address entries.+  GENERAL_NAMES* gens = static_cast<GENERAL_NAMES*>(+      X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0));+  for (int i = 0; i < sk_GENERAL_NAME_num(gens); ++i)+  {+    GENERAL_NAME* gen = sk_GENERAL_NAME_value(gens, i);+    if (gen->type == GEN_DNS && !is_address)+    {+      ASN1_IA5STRING* domain = gen->d.dNSName;+      if (domain->type == V_ASN1_IA5STRING && domain->data && domain->length)+      {+        const char* pattern = reinterpret_cast<const char*>(domain->data);+        std::size_t pattern_length = domain->length;+        if (match_pattern(pattern, pattern_length, host_.c_str()))+        {+          GENERAL_NAMES_free(gens);+          return true;+        }+      }+    }+    else if (gen->type == GEN_IPADD && is_address)+    {+      ASN1_OCTET_STRING* ip_address = gen->d.iPAddress;+      if (ip_address->type == V_ASN1_OCTET_STRING && ip_address->data)+      {+        if (address.is_v4() && ip_address->length == 4)+        {+          ip::address_v4::bytes_type bytes = address.to_v4().to_bytes();+          if (memcmp(bytes.data(), ip_address->data, 4) == 0)+          {+            GENERAL_NAMES_free(gens);+            return true;+          }+        }+        else if (address.is_v6() && ip_address->length == 16)+        {+          ip::address_v6::bytes_type bytes = address.to_v6().to_bytes();+          if (memcmp(bytes.data(), ip_address->data, 16) == 0)+          {+            GENERAL_NAMES_free(gens);+            return true;+          }+        }+      }+    }+  }+  GENERAL_NAMES_free(gens);++  // No match in the alternate names, so try the common names. We should only+  // use the "most specific" common name, which is the last one in the list.+  X509_NAME* name = X509_get_subject_name(cert);+  int i = -1;+  ASN1_STRING* common_name = 0;+  while ((i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0)+  {+    X509_NAME_ENTRY* name_entry = X509_NAME_get_entry(name, i);+    common_name = X509_NAME_ENTRY_get_data(name_entry);+  }+  if (common_name && common_name->data && common_name->length)+  {+    const char* pattern = reinterpret_cast<const char*>(common_name->data);+    std::size_t pattern_length = common_name->length;+    if (match_pattern(pattern, pattern_length, host_.c_str()))+      return true;+  }++  return false;+}++bool rfc2818_verification::match_pattern(const char* pattern,+    std::size_t pattern_length, const char* host)+{+  using namespace std; // For tolower.++  const char* p = pattern;+  const char* p_end = p + pattern_length;+  const char* h = host;++  while (p != p_end && *h)+  {+    if (*p == '*')+    {+      ++p;+      while (*h && *h != '.')+        if (match_pattern(p, p_end - p, h++))+          return true;+    }+    else if (tolower(*p) == tolower(*h))+    {+      ++p;+      ++h;+    }+    else+    {+      return false;+    }+  }++  return p == p_end && !*h;+}++} // namespace ssl+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_SSL_IMPL_RFC2818_VERIFICATION_IPP
link/modules/asio-standalone/asio/include/asio/ssl/impl/src.hpp view
@@ -2,7 +2,7 @@ // impl/ssl/src.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -24,5 +24,6 @@ #include "asio/ssl/detail/impl/engine.ipp" #include "asio/ssl/detail/impl/openssl_init.ipp" #include "asio/ssl/impl/host_name_verification.ipp"+#include "asio/ssl/impl/rfc2818_verification.ipp"  #endif // ASIO_SSL_IMPL_SRC_HPP
+ link/modules/asio-standalone/asio/include/asio/ssl/rfc2818_verification.hpp view
@@ -0,0 +1,98 @@+//+// ssl/rfc2818_verification.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_SSL_RFC2818_VERIFICATION_HPP+#define ASIO_SSL_RFC2818_VERIFICATION_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"++#if !defined(ASIO_NO_DEPRECATED)++#include <string>+#include "asio/ssl/detail/openssl_types.hpp"+#include "asio/ssl/verify_context.hpp"++#include "asio/detail/push_options.hpp"++namespace asio {+namespace ssl {++/// (Deprecated. Use ssl::host_name_verification.) Verifies a certificate+/// against a hostname according to the rules described in RFC 2818.+/**+ * @par Example+ * The following example shows how to synchronously open a secure connection to+ * a given host name:+ * @code+ * using asio::ip::tcp;+ * namespace ssl = asio::ssl;+ * typedef ssl::stream<tcp::socket> ssl_socket;+ *+ * // Create a context that uses the default paths for finding CA certificates.+ * ssl::context ctx(ssl::context::sslv23);+ * ctx.set_default_verify_paths();+ *+ * // Open a socket and connect it to the remote host.+ * asio::io_context io_context;+ * ssl_socket sock(io_context, ctx);+ * tcp::resolver resolver(io_context);+ * tcp::resolver::query query("host.name", "https");+ * asio::connect(sock.lowest_layer(), resolver.resolve(query));+ * sock.lowest_layer().set_option(tcp::no_delay(true));+ *+ * // Perform SSL handshake and verify the remote host's certificate.+ * sock.set_verify_mode(ssl::verify_peer);+ * sock.set_verify_callback(ssl::rfc2818_verification("host.name"));+ * sock.handshake(ssl_socket::client);+ *+ * // ... read and write as normal ...+ * @endcode+ */+class rfc2818_verification+{+public:+  /// The type of the function object's result.+  typedef bool result_type;++  /// Constructor.+  explicit rfc2818_verification(const std::string& host)+    : host_(host)+  {+  }++  /// Perform certificate verification.+  ASIO_DECL bool operator()(bool preverified, verify_context& ctx) const;++private:+  // Helper function to check a host name against a pattern.+  ASIO_DECL static bool match_pattern(const char* pattern,+      std::size_t pattern_length, const char* host);++  // Helper function to check a host name against an IPv4 address+  // The host name to be checked.+  std::string host_;+};++} // namespace ssl+} // namespace asio++#include "asio/detail/pop_options.hpp"++#if defined(ASIO_HEADER_ONLY)+# include "asio/ssl/impl/rfc2818_verification.ipp"+#endif // defined(ASIO_HEADER_ONLY)++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // ASIO_SSL_RFC2818_VERIFICATION_HPP
link/modules/asio-standalone/asio/include/asio/ssl/stream.hpp view
@@ -2,7 +2,7 @@ // ssl/stream.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,7 +18,6 @@ #include "asio/detail/config.hpp"  #include "asio/async_result.hpp"-#include "asio/buffer.hpp" #include "asio/detail/buffer_sequence_adapter.hpp" #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/non_const_lvalue.hpp"@@ -55,7 +54,7 @@  * @code  * asio::io_context my_context;  * asio::ssl::context ctx(asio::ssl::context::sslv23);- * asio::ssl::stream<asio::ip::tcp::socket> sock(my_context, ctx);+ * asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);  * @endcode  *  * @par Concepts:@@ -84,7 +83,7 @@   };    /// The type of the next layer.-  typedef remove_reference_t<Stream> next_layer_type;+  typedef typename remove_reference<Stream>::type next_layer_type;    /// The type of the lowest layer.   typedef typename next_layer_type::lowest_layer_type lowest_layer_type;@@ -92,6 +91,7 @@   /// The type of the executor associated with the object.   typedef typename lowest_layer_type::executor_type executor_type; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Construct a stream.   /**    * This constructor creates a stream and initialises the underlying stream@@ -103,7 +103,7 @@    */   template <typename Arg>   stream(Arg&& arg, context& ctx)-    : next_layer_(static_cast<Arg&&>(arg)),+    : next_layer_(ASIO_MOVE_CAST(Arg)(arg)),       core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())   {   }@@ -120,11 +120,27 @@    */   template <typename Arg>   stream(Arg&& arg, native_handle_type handle)-    : next_layer_(static_cast<Arg&&>(arg)),+    : next_layer_(ASIO_MOVE_CAST(Arg)(arg)),       core_(handle, next_layer_.lowest_layer().get_executor())   {   }+#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)+  template <typename Arg>+  stream(Arg& arg, context& ctx)+    : next_layer_(arg),+      core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())+  {+  } +  template <typename Arg>+  stream(Arg& arg, native_handle_type handle)+    : next_layer_(arg),+      core_(handle, next_layer_.lowest_layer().get_executor())+  {+  }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)++#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a stream from another.   /**    * @param other The other stream object from which the move will occur. Must@@ -133,8 +149,8 @@    * operation is destruction, or use as the target of a move assignment.    */   stream(stream&& other)-    : next_layer_(static_cast<Stream&&>(other.next_layer_)),-      core_(static_cast<detail::stream_core&&>(other.core_))+    : next_layer_(ASIO_MOVE_CAST(Stream)(other.next_layer_)),+      core_(ASIO_MOVE_CAST(detail::stream_core)(other.core_))   {   } @@ -149,11 +165,12 @@   {     if (this != &other)     {-      next_layer_ = static_cast<Stream&&>(other.next_layer_);-      core_ = static_cast<detail::stream_core&&>(other.core_);+      next_layer_ = ASIO_MOVE_CAST(Stream)(other.next_layer_);+      core_ = ASIO_MOVE_CAST(detail::stream_core)(other.core_);     }     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destructor.   /**@@ -171,7 +188,7 @@    *    * @return A copy of the executor that stream will use to dispatch handlers.    */-  executor_type get_executor() noexcept+  executor_type get_executor() ASIO_NOEXCEPT   {     return next_layer_.lowest_layer().get_executor();   }@@ -187,7 +204,7 @@    * suitable for passing to functions such as @c SSL_get_verify_result and    * @c SSL_get_peer_certificate:    * @code-   * asio::ssl::stream<asio::ip::tcp::socket> sock(io_ctx, ctx);+   * asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);    *    * // ... establish connection and perform handshake ...    *@@ -481,7 +498,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -499,13 +516,17 @@    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        HandshakeToken = default_completion_token_t<executor_type>>-  auto async_handshake(handshake_type type,-      HandshakeToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        HandshakeToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(HandshakeToken,+      void (asio::error_code))+  async_handshake(handshake_type type,+      ASIO_MOVE_ARG(HandshakeToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<HandshakeToken,         void (asio::error_code)>(-          declval<initiate_async_handshake>(), token, type))+          declval<initiate_async_handshake>(), token, type)))   {     return async_initiate<HandshakeToken,       void (asio::error_code)>(@@ -538,7 +559,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -557,17 +578,16 @@   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,         std::size_t)) BufferedHandshakeToken-          = default_completion_token_t<executor_type>>-  auto async_handshake(handshake_type type, const ConstBufferSequence& buffers,-      BufferedHandshakeToken&& token-        = default_completion_token_t<executor_type>(),-      constraint_t<-        is_const_buffer_sequence<ConstBufferSequence>::value-      > = 0)-    -> decltype(+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(BufferedHandshakeToken,+      void (asio::error_code, std::size_t))+  async_handshake(handshake_type type, const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(BufferedHandshakeToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<BufferedHandshakeToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_buffered_handshake>(), token, type, buffers))+          declval<initiate_async_buffered_handshake>(), token, type, buffers)))   {     return async_initiate<BufferedHandshakeToken,       void (asio::error_code, std::size_t)>(@@ -618,7 +638,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode@@ -637,13 +657,16 @@   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))         ShutdownToken-          = default_completion_token_t<executor_type>>-  auto async_shutdown(-      ShutdownToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ShutdownToken,+      void (asio::error_code))+  async_shutdown(+      ASIO_MOVE_ARG(ShutdownToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ShutdownToken,         void (asio::error_code)>(-          declval<initiate_async_shutdown>(), token))+          declval<initiate_async_shutdown>(), token)))   {     return async_initiate<ShutdownToken,       void (asio::error_code)>(@@ -722,7 +745,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -745,13 +768,17 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_write_some>(), token, buffers))+          declval<initiate_async_write_some>(), token, buffers)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -830,7 +857,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -853,13 +880,17 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_read_some>(), token, buffers))+          declval<initiate_async_read_some>(), token, buffers)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -877,13 +908,13 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename HandshakeHandler>-    void operator()(HandshakeHandler&& handler,+    void operator()(ASIO_MOVE_ARG(HandshakeHandler) handler,         handshake_type type) const     {       // If you get an error on the following line it means that your handler@@ -909,13 +940,13 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename BufferedHandshakeHandler, typename ConstBufferSequence>-    void operator()(BufferedHandshakeHandler&& handler,+    void operator()(ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,         handshake_type type, const ConstBufferSequence& buffers) const     {       // If you get an error on the following line it means that your@@ -945,13 +976,13 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ShutdownHandler>-    void operator()(ShutdownHandler&& handler) const+    void operator()(ASIO_MOVE_ARG(ShutdownHandler) handler) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a ShutdownHandler.@@ -976,13 +1007,13 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler@@ -1008,13 +1039,13 @@     {     } -    executor_type get_executor() const noexcept+    executor_type get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/ssl/stream_base.hpp view
@@ -2,7 +2,7 @@ // ssl/stream_base.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ssl/verify_context.hpp view
@@ -2,7 +2,7 @@ // ssl/verify_context.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ssl/verify_mode.hpp view
@@ -2,7 +2,7 @@ // ssl/verify_mode.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/static_thread_pool.hpp view
@@ -2,7 +2,7 @@ // static_thread_pool.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/steady_timer.hpp view
@@ -2,7 +2,7 @@ // steady_timer.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)+ #include "asio/basic_waitable_timer.hpp" #include "asio/detail/chrono.hpp" @@ -33,5 +36,7 @@ typedef basic_waitable_timer<chrono::steady_clock> steady_timer;  } // namespace asio++#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_STEADY_TIMER_HPP
link/modules/asio-standalone/asio/include/asio/strand.hpp view
@@ -2,7 +2,7 @@ // strand.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -48,20 +48,20 @@   /// Construct a strand for the specified executor.   template <typename Executor1>   explicit strand(const Executor1& e,-      constraint_t<-        conditional_t<+      typename constraint<+        conditional<           !is_same<Executor1, strand>::value,           is_convertible<Executor1, Executor>,           false_type-        >::value-      > = 0)+        >::type::value+      >::type = 0)     : executor_(e),       impl_(strand::create_implementation(executor_))   {   }    /// Copy constructor.-  strand(const strand& other) noexcept+  strand(const strand& other) ASIO_NOEXCEPT     : executor_(other.executor_),       impl_(other.impl_)   {@@ -74,14 +74,14 @@    */   template <class OtherExecutor>   strand(-      const strand<OtherExecutor>& other) noexcept+      const strand<OtherExecutor>& other) ASIO_NOEXCEPT     : executor_(other.executor_),       impl_(other.impl_)   {   }    /// Assignment operator.-  strand& operator=(const strand& other) noexcept+  strand& operator=(const strand& other) ASIO_NOEXCEPT   {     executor_ = other.executor_;     impl_ = other.impl_;@@ -95,17 +95,18 @@    */   template <class OtherExecutor>   strand& operator=(-      const strand<OtherExecutor>& other) noexcept+      const strand<OtherExecutor>& other) ASIO_NOEXCEPT   {     executor_ = other.executor_;     impl_ = other.impl_;     return *this;   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.-  strand(strand&& other) noexcept-    : executor_(static_cast<Executor&&>(other.executor_)),-      impl_(static_cast<implementation_type&&>(other.impl_))+  strand(strand&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(Executor)(other.executor_)),+      impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_))   {   } @@ -115,17 +116,17 @@    * to @c Executor.    */   template <class OtherExecutor>-  strand(strand<OtherExecutor>&& other) noexcept-    : executor_(static_cast<OtherExecutor&&>(other.executor_)),-      impl_(static_cast<implementation_type&&>(other.impl_))+  strand(strand<OtherExecutor>&& other) ASIO_NOEXCEPT+    : executor_(ASIO_MOVE_CAST(OtherExecutor)(other.executor_)),+      impl_(ASIO_MOVE_CAST(implementation_type)(other.impl_))   {   }    /// Move assignment operator.-  strand& operator=(strand&& other) noexcept+  strand& operator=(strand&& other) ASIO_NOEXCEPT   {-    executor_ = static_cast<Executor&&>(other.executor_);-    impl_ = static_cast<implementation_type&&>(other.impl_);+    executor_ = ASIO_MOVE_CAST(Executor)(other.executor_);+    impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_);     return *this;   } @@ -135,20 +136,21 @@    * convertible to @c Executor.    */   template <class OtherExecutor>-  strand& operator=(strand<OtherExecutor>&& other) noexcept+  strand& operator=(strand<OtherExecutor>&& other) ASIO_NOEXCEPT   {-    executor_ = static_cast<OtherExecutor&&>(other.executor_);-    impl_ = static_cast<implementation_type&&>(other.impl_);+    executor_ = ASIO_MOVE_CAST(OtherExecutor)(other.executor_);+    impl_ = ASIO_MOVE_CAST(implementation_type)(other.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destructor.-  ~strand() noexcept+  ~strand() ASIO_NOEXCEPT   {   }    /// Obtain the underlying executor.-  inner_executor_type get_inner_executor() const noexcept+  inner_executor_type get_inner_executor() const ASIO_NOEXCEPT   {     return executor_;   }@@ -165,15 +167,16 @@    *   ... @endcode    */   template <typename Property>-  constraint_t<+  typename constraint<     can_query<const Executor&, Property>::value,-    conditional_t<+    typename conditional<       is_convertible<Property, execution::blocking_t>::value,       execution::blocking_t,-      query_result_t<const Executor&, Property>-    >-  > query(const Property& p) const-    noexcept(is_nothrow_query<const Executor&, Property>::value)+      typename query_result<const Executor&, Property>::type+    >::type+  >::type query(const Property& p) const+    ASIO_NOEXCEPT_IF((+      is_nothrow_query<const Executor&, Property>::value))   {     return this->query_helper(         is_convertible<Property, execution::blocking_t>(), p);@@ -190,15 +193,19 @@    *     asio::execution::blocking.never); @endcode    */   template <typename Property>-  constraint_t<+  typename constraint<     can_require<const Executor&, Property>::value       && !is_convertible<Property, execution::blocking_t::always_t>::value,-    strand<decay_t<require_result_t<const Executor&, Property>>>-  > require(const Property& p) const-    noexcept(is_nothrow_require<const Executor&, Property>::value)+    strand<typename decay<+      typename require_result<const Executor&, Property>::type+    >::type>+  >::type require(const Property& p) const+    ASIO_NOEXCEPT_IF((+      is_nothrow_require<const Executor&, Property>::value))   {-    return strand<decay_t<require_result_t<const Executor&, Property>>>(-        asio::require(executor_, p), impl_);+    return strand<typename decay<+      typename require_result<const Executor&, Property>::type+        >::type>(asio::require(executor_, p), impl_);   }    /// Forward a preference to the underlying executor.@@ -212,20 +219,24 @@    *     asio::execution::blocking.never); @endcode    */   template <typename Property>-  constraint_t<+  typename constraint<     can_prefer<const Executor&, Property>::value       && !is_convertible<Property, execution::blocking_t::always_t>::value,-    strand<decay_t<prefer_result_t<const Executor&, Property>>>-  > prefer(const Property& p) const-    noexcept(is_nothrow_prefer<const Executor&, Property>::value)+    strand<typename decay<+      typename prefer_result<const Executor&, Property>::type+    >::type>+  >::type prefer(const Property& p) const+    ASIO_NOEXCEPT_IF((+      is_nothrow_prefer<const Executor&, Property>::value))   {-    return strand<decay_t<prefer_result_t<const Executor&, Property>>>(-        asio::prefer(executor_, p), impl_);+    return strand<typename decay<+      typename prefer_result<const Executor&, Property>::type+        >::type>(asio::prefer(executor_, p), impl_);   }  #if !defined(ASIO_NO_TS_EXECUTORS)   /// Obtain the underlying execution context.-  execution_context& context() const noexcept+  execution_context& context() const ASIO_NOEXCEPT   {     return executor_.context();   }@@ -234,7 +245,7 @@   /**    * The strand delegates this call to its underlying executor.    */-  void on_work_started() const noexcept+  void on_work_started() const ASIO_NOEXCEPT   {     executor_.on_work_started();   }@@ -243,7 +254,7 @@   /**    * The strand delegates this call to its underlying executor.    */-  void on_work_finished() const noexcept+  void on_work_finished() const ASIO_NOEXCEPT   {     executor_.on_work_finished();   }@@ -260,13 +271,20 @@    * function object must be: @code void function(); @endcode    */   template <typename Function>-  constraint_t<+  typename constraint<+#if defined(ASIO_NO_DEPRECATED) \+  || defined(GENERATING_DOCUMENTATION)     traits::execute_member<const Executor&, Function>::is_valid,+#else // defined(ASIO_NO_DEPRECATED)+      //   || defined(GENERATING_DOCUMENTATION)+    execution::can_execute<const Executor&, Function>::value,+#endif // defined(ASIO_NO_DEPRECATED)+       //   || defined(GENERATING_DOCUMENTATION)     void-  > execute(Function&& f) const+  >::type execute(ASIO_MOVE_ARG(Function) f) const   {     detail::strand_executor_service::execute(impl_,-        executor_, static_cast<Function&&>(f));+        executor_, ASIO_MOVE_CAST(Function)(f));   }  #if !defined(ASIO_NO_TS_EXECUTORS)@@ -286,10 +304,10 @@    * internal storage needed for function invocation.    */   template <typename Function, typename Allocator>-  void dispatch(Function&& f, const Allocator& a) const+  void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const   {     detail::strand_executor_service::dispatch(impl_,-        executor_, static_cast<Function&&>(f), a);+        executor_, ASIO_MOVE_CAST(Function)(f), a);   }    /// Request the strand to invoke the given function object.@@ -306,10 +324,10 @@    * internal storage needed for function invocation.    */   template <typename Function, typename Allocator>-  void post(Function&& f, const Allocator& a) const+  void post(ASIO_MOVE_ARG(Function) f, const Allocator& a) const   {     detail::strand_executor_service::post(impl_,-        executor_, static_cast<Function&&>(f), a);+        executor_, ASIO_MOVE_CAST(Function)(f), a);   }    /// Request the strand to invoke the given function object.@@ -326,10 +344,10 @@    * internal storage needed for function invocation.    */   template <typename Function, typename Allocator>-  void defer(Function&& f, const Allocator& a) const+  void defer(ASIO_MOVE_ARG(Function) f, const Allocator& a) const   {     detail::strand_executor_service::defer(impl_,-        executor_, static_cast<Function&&>(f), a);+        executor_, ASIO_MOVE_CAST(Function)(f), a);   } #endif // !defined(ASIO_NO_TS_EXECUTORS) @@ -339,7 +357,7 @@    * submitted to the strand using post(), dispatch() or defer(). Otherwise    * returns @c false.    */-  bool running_in_this_thread() const noexcept+  bool running_in_this_thread() const ASIO_NOEXCEPT   {     return detail::strand_executor_service::running_in_this_thread(impl_);   }@@ -349,7 +367,7 @@    * Two strands are equal if they refer to the same ordered, non-concurrent    * state.    */-  friend bool operator==(const strand& a, const strand& b) noexcept+  friend bool operator==(const strand& a, const strand& b) ASIO_NOEXCEPT   {     return a.impl_ == b.impl_;   }@@ -359,7 +377,7 @@    * Two strands are equal if they refer to the same ordered, non-concurrent    * state.    */-  friend bool operator!=(const strand& a, const strand& b) noexcept+  friend bool operator!=(const strand& a, const strand& b) ASIO_NOEXCEPT   {     return a.impl_ != b.impl_;   }@@ -372,9 +390,9 @@    template <typename InnerExecutor>   static implementation_type create_implementation(const InnerExecutor& ex,-      constraint_t<+      typename constraint<         can_query<InnerExecutor, execution::context_t>::value-      > = 0)+      >::type = 0)   {     return use_service<detail::strand_executor_service>(         asio::query(ex, execution::context)).create_implementation();@@ -382,9 +400,9 @@    template <typename InnerExecutor>   static implementation_type create_implementation(const InnerExecutor& ex,-      constraint_t<+      typename constraint<         !can_query<InnerExecutor, execution::context_t>::value-      > = 0)+      >::type = 0)   {     return use_service<detail::strand_executor_service>(         ex.context()).create_implementation();@@ -397,7 +415,7 @@   }    template <typename Property>-  query_result_t<const Executor&, Property> query_helper(+  typename query_result<const Executor&, Property>::type query_helper(       false_type, const Property& property) const   {     return asio::query(executor_, property);@@ -430,9 +448,9 @@  */ template <typename Executor> inline strand<Executor> make_strand(const Executor& ex,-    constraint_t<+    typename constraint<       is_executor<Executor>::value || execution::is_executor<Executor>::value-    > = 0)+    >::type = 0) {   return strand<Executor>(ex); }@@ -447,9 +465,9 @@ template <typename ExecutionContext> inline strand<typename ExecutionContext::executor_type> make_strand(ExecutionContext& ctx,-    constraint_t<+    typename constraint<       is_convertible<ExecutionContext&, execution_context&>::value-    > = 0)+    >::type = 0) {   return strand<typename ExecutionContext::executor_type>(ctx.get_executor()); }@@ -463,10 +481,10 @@ #if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)  template <typename Executor>-struct equality_comparable<strand<Executor>>+struct equality_comparable<strand<Executor> > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); };  #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -475,12 +493,16 @@  template <typename Executor, typename Function> struct execute_member<strand<Executor>, Function,-    enable_if_t<+    typename enable_if<+#if defined(ASIO_NO_DEPRECATED)       traits::execute_member<const Executor&, Function>::is_valid-    >>+#else // defined(ASIO_NO_DEPRECATED)+      execution::can_execute<const Executor&, Function>::value+#endif // defined(ASIO_NO_DEPRECATED)+    >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; }; @@ -490,16 +512,17 @@  template <typename Executor, typename Property> struct query_member<strand<Executor>, Property,-    enable_if_t<+    typename enable_if<       can_query<const Executor&, Property>::value-    >>+    >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_query<Executor, Property>::value;-  typedef conditional_t<+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_query<Executor, Property>::value));+  typedef typename conditional<     is_convertible<Property, execution::blocking_t>::value,-      execution::blocking_t, query_result_t<Executor, Property>> result_type;+      execution::blocking_t, typename query_result<Executor, Property>::type+        >::type result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -508,15 +531,17 @@  template <typename Executor, typename Property> struct require_member<strand<Executor>, Property,-    enable_if_t<+    typename enable_if<       can_require<const Executor&, Property>::value         && !is_convertible<Property, execution::blocking_t::always_t>::value-    >>+    >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_require<Executor, Property>::value;-  typedef strand<decay_t<require_result_t<Executor, Property>>> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_require<Executor, Property>::value));+  typedef strand<typename decay<+    typename require_result<Executor, Property>::type+      >::type> result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -525,15 +550,17 @@  template <typename Executor, typename Property> struct prefer_member<strand<Executor>, Property,-    enable_if_t<+    typename enable_if<       can_prefer<const Executor&, Property>::value         && !is_convertible<Property, execution::blocking_t::always_t>::value-    >>+    >::type> {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept =-    is_nothrow_prefer<Executor, Property>::value;-  typedef strand<decay_t<prefer_result_t<Executor, Property>>> result_type;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+      (is_nothrow_prefer<Executor, Property>::value));+  typedef strand<typename decay<+    typename prefer_result<Executor, Property>::type+      >::type> result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)
link/modules/asio-standalone/asio/include/asio/stream_file.hpp view
@@ -2,7 +2,7 @@ // stream_file.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/streambuf.hpp view
@@ -2,7 +2,7 @@ // streambuf.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/system_context.hpp view
@@ -2,7 +2,7 @@ // system_context.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -43,13 +43,13 @@   ASIO_DECL ~system_context();    /// Obtain an executor for the context.-  executor_type get_executor() noexcept;+  executor_type get_executor() ASIO_NOEXCEPT;    /// Signal all threads in the system thread pool to stop.   ASIO_DECL void stop();    /// Determine whether the system thread pool has been stopped.-  ASIO_DECL bool stopped() const noexcept;+  ASIO_DECL bool stopped() const ASIO_NOEXCEPT;    /// Join all threads in the system thread pool.   ASIO_DECL void join();@@ -72,7 +72,7 @@   detail::scheduler& scheduler_;    // The threads in the system thread pool.-  detail::thread_group<std::allocator<void>> threads_;+  detail::thread_group threads_;    // The number of threads in the pool.   std::size_t num_threads_;
link/modules/asio-standalone/asio/include/asio/system_error.hpp view
@@ -2,7 +2,7 @@ // system_error.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,13 +16,113 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include <system_error> +#if defined(ASIO_HAS_STD_SYSTEM_ERROR)+# include <system_error>+#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)+# include <cerrno>+# include <exception>+# include <string>+# include "asio/error_code.hpp"+# include "asio/detail/scoped_ptr.hpp"+#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)+ #include "asio/detail/push_options.hpp"  namespace asio { +#if defined(ASIO_HAS_STD_SYSTEM_ERROR)+ typedef std::system_error system_error;++#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)++/// The system_error class is used to represent system conditions that+/// prevent the library from operating correctly.+class system_error+  : public std::exception+{+public:+  /// Construct with an error code.+  system_error(const error_code& ec)+    : code_(ec),+      context_()+  {+  }++  /// Construct with an error code and context.+  system_error(const error_code& ec, const std::string& context)+    : code_(ec),+      context_(context)+  {+  }++  /// Copy constructor.+  system_error(const system_error& other)+    : std::exception(other),+      code_(other.code_),+      context_(other.context_),+      what_()+  {+  }++  /// Destructor.+  virtual ~system_error() throw ()+  {+  }++  /// Assignment operator.+  system_error& operator=(const system_error& e)+  {+    context_ = e.context_;+    code_ = e.code_;+    what_.reset();+    return *this;+  }++  /// Get a string representation of the exception.+  virtual const char* what() const throw ()+  {+#if !defined(ASIO_NO_EXCEPTIONS)+    try+#endif // !defined(ASIO_NO_EXCEPTIONS)+    {+      if (!what_.get())+      {+        std::string tmp(context_);+        if (tmp.length())+          tmp += ": ";+        tmp += code_.message();+        what_.reset(new std::string(tmp));+      }+      return what_->c_str();+    }+#if !defined(ASIO_NO_EXCEPTIONS)+    catch (std::exception&)+    {+      return "system_error";+    }+#endif // !defined(ASIO_NO_EXCEPTIONS)+  }++  /// Get the error code associated with the exception.+  error_code code() const+  {+    return code_;+  }++private:+  // The code associated with the error.+  error_code code_;++  // The context associated with the error.+  std::string context_;++  // The string representation of the error.+  mutable asio::detail::scoped_ptr<std::string> what_;+};++#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/system_executor.hpp view
@@ -2,7 +2,7 @@ // system_executor.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -39,7 +39,7 @@ { public:   /// Default constructor.-  basic_system_executor() noexcept+  basic_system_executor() ASIO_NOEXCEPT     : allocator_(Allocator())   {   }@@ -168,11 +168,11 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::allocator); @endcode    */-  basic_system_executor<Blocking, Relationship, std::allocator<void>>+  basic_system_executor<Blocking, Relationship, std::allocator<void> >   require(execution::allocator_t<void>) const   {     return basic_system_executor<Blocking,-        Relationship, std::allocator<void>>();+        Relationship, std::allocator<void> >();   }  #if !defined(GENERATING_DOCUMENTATION)@@ -195,8 +195,8 @@    *       == asio::execution::mapping.thread)    *   ... @endcode    */-  static constexpr execution::mapping_t query(-      execution::mapping_t) noexcept+  static ASIO_CONSTEXPR execution::mapping_t query(+      execution::mapping_t) ASIO_NOEXCEPT   {     return execution::mapping.thread;   }@@ -211,7 +211,7 @@    * asio::system_context& pool = asio::query(    *     ex, asio::execution::context); @endcode    */-  static system_context& query(execution::context_t) noexcept;+  static system_context& query(execution::context_t) ASIO_NOEXCEPT;    /// Query the current value of the @c blocking property.   /**@@ -224,8 +224,8 @@    *       == asio::execution::blocking.always)    *   ... @endcode    */-  static constexpr execution::blocking_t query(-      execution::blocking_t) noexcept+  static ASIO_CONSTEXPR execution::blocking_t query(+      execution::blocking_t) ASIO_NOEXCEPT   {     return Blocking();   }@@ -241,8 +241,8 @@    *       == asio::execution::relationship.continuation)    *   ... @endcode    */-  static constexpr execution::relationship_t query(-      execution::relationship_t) noexcept+  static ASIO_CONSTEXPR execution::relationship_t query(+      execution::relationship_t) ASIO_NOEXCEPT   {     return Relationship();   }@@ -258,8 +258,8 @@    *     asio::execution::allocator); @endcode    */   template <typename OtherAllocator>-  constexpr Allocator query(-      execution::allocator_t<OtherAllocator>) const noexcept+  ASIO_CONSTEXPR Allocator query(+      execution::allocator_t<OtherAllocator>) const ASIO_NOEXCEPT   {     return allocator_;   }@@ -274,8 +274,8 @@    * auto alloc = asio::query(ex,    *     asio::execution::allocator); @endcode    */-  constexpr Allocator query(-      execution::allocator_t<void>) const noexcept+  ASIO_CONSTEXPR Allocator query(+      execution::allocator_t<void>) const ASIO_NOEXCEPT   {     return allocator_;   }@@ -291,7 +291,7 @@    * std::size_t occupancy = asio::query(    *     ex, asio::execution::occupancy); @endcode    */-  std::size_t query(execution::occupancy_t) const noexcept;+  std::size_t query(execution::occupancy_t) const ASIO_NOEXCEPT;  public:   /// Compare two executors for equality.@@ -299,7 +299,7 @@    * Two executors are equal if they refer to the same underlying io_context.    */   friend bool operator==(const basic_system_executor&,-      const basic_system_executor&) noexcept+      const basic_system_executor&) ASIO_NOEXCEPT   {     return true;   }@@ -309,28 +309,28 @@    * Two executors are equal if they refer to the same underlying io_context.    */   friend bool operator!=(const basic_system_executor&,-      const basic_system_executor&) noexcept+      const basic_system_executor&) ASIO_NOEXCEPT   {     return false;   }    /// Execution function.   template <typename Function>-  void execute(Function&& f) const+  void execute(ASIO_MOVE_ARG(Function) f) const   {-    this->do_execute(static_cast<Function&&>(f), Blocking());+    this->do_execute(ASIO_MOVE_CAST(Function)(f), Blocking());   }  #if !defined(ASIO_NO_TS_EXECUTORS) public:   /// Obtain the underlying execution context.-  system_context& context() const noexcept;+  system_context& context() const ASIO_NOEXCEPT;    /// Inform the executor that it has some outstanding work to do.   /**    * For the system executor, this is a no-op.    */-  void on_work_started() const noexcept+  void on_work_started() const ASIO_NOEXCEPT   {   } @@ -338,7 +338,7 @@   /**    * For the system executor, this is a no-op.    */-  void on_work_finished() const noexcept+  void on_work_finished() const ASIO_NOEXCEPT   {   } @@ -355,7 +355,7 @@    * internal storage needed for function invocation.    */   template <typename Function, typename OtherAllocator>-  void dispatch(Function&& f, const OtherAllocator& a) const;+  void dispatch(ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const;    /// Request the system executor to invoke the given function object.   /**@@ -371,7 +371,7 @@    * internal storage needed for function invocation.    */   template <typename Function, typename OtherAllocator>-  void post(Function&& f, const OtherAllocator& a) const;+  void post(ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const;    /// Request the system executor to invoke the given function object.   /**@@ -387,7 +387,7 @@    * internal storage needed for function invocation.    */   template <typename Function, typename OtherAllocator>-  void defer(Function&& f, const OtherAllocator& a) const;+  void defer(ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const; #endif // !defined(ASIO_NO_TS_EXECUTORS)  private:@@ -401,17 +401,17 @@    /// Execution helper implementation for the possibly blocking property.   template <typename Function>-  void do_execute(Function&& f,+  void do_execute(ASIO_MOVE_ARG(Function) f,       execution::blocking_t::possibly_t) const;    /// Execution helper implementation for the always blocking property.   template <typename Function>-  void do_execute(Function&& f,+  void do_execute(ASIO_MOVE_ARG(Function) f,       execution::blocking_t::always_t) const;    /// Execution helper implementation for the never blocking property.   template <typename Function>-  void do_execute(Function&& f,+  void do_execute(ASIO_MOVE_ARG(Function) f,       execution::blocking_t::never_t) const;    // The allocator used for execution functions.@@ -428,7 +428,7 @@  * immediately.  */ typedef basic_system_executor<execution::blocking_t::possibly_t,-    execution::relationship_t::fork_t, std::allocator<void>>+    execution::relationship_t::fork_t, std::allocator<void> >   system_executor;  #if !defined(GENERATING_DOCUMENTATION)@@ -442,8 +442,8 @@     asio::basic_system_executor<Blocking, Relationship, Allocator>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); };  #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -457,8 +457,8 @@     Function   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; }; @@ -472,8 +472,8 @@     asio::execution::blocking_t::possibly_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::basic_system_executor<       asio::execution::blocking_t::possibly_t,       Relationship, Allocator> result_type;@@ -485,8 +485,8 @@     asio::execution::blocking_t::always_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::basic_system_executor<       asio::execution::blocking_t::always_t,       Relationship, Allocator> result_type;@@ -498,8 +498,8 @@     asio::execution::blocking_t::never_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::basic_system_executor<       asio::execution::blocking_t::never_t,       Relationship, Allocator> result_type;@@ -511,8 +511,8 @@     asio::execution::relationship_t::fork_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::basic_system_executor<Blocking,       asio::execution::relationship_t::fork_t,       Allocator> result_type;@@ -524,8 +524,8 @@     asio::execution::relationship_t::continuation_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::basic_system_executor<Blocking,       asio::execution::relationship_t::continuation_t,       Allocator> result_type;@@ -537,10 +537,10 @@     asio::execution::allocator_t<void>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::basic_system_executor<Blocking,-      Relationship, std::allocator<void>> result_type;+      Relationship, std::allocator<void> > result_type; };  template <typename Blocking, typename Relationship,@@ -550,8 +550,8 @@     asio::execution::allocator_t<OtherAllocator>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::basic_system_executor<Blocking,       Relationship, OtherAllocator> result_type; };@@ -573,11 +573,11 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::mapping_t::thread_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -600,8 +600,8 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::blocking_t result_type; }; @@ -618,8 +618,8 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::relationship_t result_type; }; @@ -629,8 +629,8 @@     asio::execution::context_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::system_context& result_type; }; @@ -640,8 +640,8 @@     asio::execution::allocator_t<void>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef Allocator result_type; }; @@ -651,8 +651,8 @@     asio::execution::allocator_t<Allocator>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef Allocator result_type; }; 
link/modules/asio-standalone/asio/include/asio/system_timer.hpp view
@@ -2,7 +2,7 @@ // system_timer.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,6 +16,9 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"++#if defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)+ #include "asio/basic_waitable_timer.hpp" #include "asio/detail/chrono.hpp" @@ -33,5 +36,7 @@ typedef basic_waitable_timer<chrono::system_clock> system_timer;  } // namespace asio++#endif // defined(ASIO_HAS_CHRONO) || defined(GENERATING_DOCUMENTATION)  #endif // ASIO_SYSTEM_TIMER_HPP
link/modules/asio-standalone/asio/include/asio/this_coro.hpp view
@@ -2,7 +2,7 @@ // this_coro.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -26,18 +26,22 @@ /// Awaitable type that returns the executor of the current coroutine. struct executor_t {-  constexpr executor_t()+  ASIO_CONSTEXPR executor_t()   {   } };  /// Awaitable object that returns the executor of the current coroutine.-ASIO_INLINE_VARIABLE constexpr executor_t executor;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr executor_t executor;+#elif defined(ASIO_MSVC)+__declspec(selectany) executor_t executor;+#endif  /// Awaitable type that returns the cancellation state of the current coroutine. struct cancellation_state_t {-  constexpr cancellation_state_t()+  ASIO_CONSTEXPR cancellation_state_t()   {   } };@@ -57,7 +61,11 @@  *     // ...  * } @endcode  */-ASIO_INLINE_VARIABLE constexpr cancellation_state_t cancellation_state;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr cancellation_state_t cancellation_state;+#elif defined(ASIO_MSVC)+__declspec(selectany) cancellation_state_t cancellation_state;+#endif  #if defined(GENERATING_DOCUMENTATION) @@ -80,7 +88,7 @@  * @note The cancellation state is shared by all coroutines in the same "thread  * of execution" that was created using asio::co_spawn.  */-ASIO_NODISCARD constexpr unspecified+ASIO_NODISCARD ASIO_CONSTEXPR unspecified reset_cancellation_state();  /// Returns an awaitable object that may be used to reset the cancellation state@@ -105,8 +113,8 @@  * of execution" that was created using asio::co_spawn.  */ template <typename Filter>-ASIO_NODISCARD constexpr unspecified-reset_cancellation_state(Filter&& filter);+ASIO_NODISCARD ASIO_CONSTEXPR unspecified+reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter);  /// Returns an awaitable object that may be used to reset the cancellation state /// of the current coroutine.@@ -132,10 +140,10 @@  * of execution" that was created using asio::co_spawn.  */ template <typename InFilter, typename OutFilter>-ASIO_NODISCARD constexpr unspecified+ASIO_NODISCARD ASIO_CONSTEXPR unspecified reset_cancellation_state(-    InFilter&& in_filter,-    OutFilter&& out_filter);+    ASIO_MOVE_ARG(InFilter) in_filter,+    ASIO_MOVE_ARG(OutFilter) out_filter);  /// Returns an awaitable object that may be used to determine whether the /// coroutine throws if trying to suspend when it has been cancelled.@@ -149,7 +157,7 @@  *   // ...  * } @endcode  */-ASIO_NODISCARD constexpr unspecified+ASIO_NODISCARD ASIO_CONSTEXPR unspecified throw_if_cancelled();  /// Returns an awaitable object that may be used to specify whether the@@ -163,19 +171,19 @@  *   // ...  * } @endcode  */-ASIO_NODISCARD constexpr unspecified+ASIO_NODISCARD ASIO_CONSTEXPR unspecified throw_if_cancelled(bool value);  #else // defined(GENERATING_DOCUMENTATION)  struct reset_cancellation_state_0_t {-  constexpr reset_cancellation_state_0_t()+  ASIO_CONSTEXPR reset_cancellation_state_0_t()   {   } }; -ASIO_NODISCARD inline constexpr reset_cancellation_state_0_t+ASIO_NODISCARD inline ASIO_CONSTEXPR reset_cancellation_state_0_t reset_cancellation_state() {   return reset_cancellation_state_0_t();@@ -185,9 +193,9 @@ struct reset_cancellation_state_1_t {   template <typename F>-  explicit constexpr reset_cancellation_state_1_t(-      F&& filt)-    : filter(static_cast<F&&>(filt))+  explicit ASIO_CONSTEXPR reset_cancellation_state_1_t(+      ASIO_MOVE_ARG(F) filt)+    : filter(ASIO_MOVE_CAST(F)(filt))   {   } @@ -195,22 +203,22 @@ };  template <typename Filter>-ASIO_NODISCARD inline constexpr reset_cancellation_state_1_t<-    decay_t<Filter>>-reset_cancellation_state(Filter&& filter)+ASIO_NODISCARD inline ASIO_CONSTEXPR reset_cancellation_state_1_t<+    typename decay<Filter>::type>+reset_cancellation_state(ASIO_MOVE_ARG(Filter) filter) {-  return reset_cancellation_state_1_t<decay_t<Filter>>(-      static_cast<Filter&&>(filter));+  return reset_cancellation_state_1_t<typename decay<Filter>::type>(+      ASIO_MOVE_CAST(Filter)(filter)); }  template <typename InFilter, typename OutFilter> struct reset_cancellation_state_2_t {   template <typename F1, typename F2>-  constexpr reset_cancellation_state_2_t(-      F1&& in_filt, F2&& out_filt)-    : in_filter(static_cast<F1&&>(in_filt)),-      out_filter(static_cast<F2&&>(out_filt))+  ASIO_CONSTEXPR reset_cancellation_state_2_t(+      ASIO_MOVE_ARG(F1) in_filt, ASIO_MOVE_ARG(F2) out_filt)+    : in_filter(ASIO_MOVE_CAST(F1)(in_filt)),+      out_filter(ASIO_MOVE_CAST(F2)(out_filt))   {   } @@ -219,23 +227,28 @@ };  template <typename InFilter, typename OutFilter>-ASIO_NODISCARD inline constexpr-reset_cancellation_state_2_t<decay_t<InFilter>, decay_t<OutFilter>>-reset_cancellation_state(InFilter&& in_filter, OutFilter&& out_filter)+ASIO_NODISCARD inline ASIO_CONSTEXPR reset_cancellation_state_2_t<+    typename decay<InFilter>::type,+    typename decay<OutFilter>::type>+reset_cancellation_state(+    ASIO_MOVE_ARG(InFilter) in_filter,+    ASIO_MOVE_ARG(OutFilter) out_filter) {-  return reset_cancellation_state_2_t<decay_t<InFilter>, decay_t<OutFilter>>(-      static_cast<InFilter&&>(in_filter),-      static_cast<OutFilter&&>(out_filter));+  return reset_cancellation_state_2_t<+      typename decay<InFilter>::type,+      typename decay<OutFilter>::type>(+        ASIO_MOVE_CAST(InFilter)(in_filter),+        ASIO_MOVE_CAST(OutFilter)(out_filter)); }  struct throw_if_cancelled_0_t {-  constexpr throw_if_cancelled_0_t()+  ASIO_CONSTEXPR throw_if_cancelled_0_t()   {   } }; -ASIO_NODISCARD inline constexpr throw_if_cancelled_0_t+ASIO_NODISCARD inline ASIO_CONSTEXPR throw_if_cancelled_0_t throw_if_cancelled() {   return throw_if_cancelled_0_t();@@ -243,7 +256,7 @@  struct throw_if_cancelled_1_t {-  explicit constexpr throw_if_cancelled_1_t(bool val)+  explicit ASIO_CONSTEXPR throw_if_cancelled_1_t(bool val)     : value(val)   {   }@@ -251,7 +264,7 @@   bool value; }; -ASIO_NODISCARD inline constexpr throw_if_cancelled_1_t+ASIO_NODISCARD inline ASIO_CONSTEXPR throw_if_cancelled_1_t throw_if_cancelled(bool value) {   return throw_if_cancelled_1_t(value);
link/modules/asio-standalone/asio/include/asio/thread.hpp view
@@ -2,7 +2,7 @@ // thread.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/thread_pool.hpp view
@@ -2,7 +2,7 @@ // thread_pool.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -28,11 +28,11 @@ namespace detail {   struct thread_pool_bits   {-    static constexpr unsigned int blocking_never = 1;-    static constexpr unsigned int blocking_always = 2;-    static constexpr unsigned int blocking_mask = 3;-    static constexpr unsigned int relationship_continuation = 4;-    static constexpr unsigned int outstanding_work_tracked = 8;+    ASIO_STATIC_CONSTEXPR(unsigned int, blocking_never = 1);+    ASIO_STATIC_CONSTEXPR(unsigned int, blocking_always = 2);+    ASIO_STATIC_CONSTEXPR(unsigned int, blocking_mask = 3);+    ASIO_STATIC_CONSTEXPR(unsigned int, relationship_continuation = 4);+    ASIO_STATIC_CONSTEXPR(unsigned int, outstanding_work_tracked = 8);   }; } // namespace detail @@ -41,17 +41,6 @@  * The thread pool class is an execution context where functions are permitted  * to run on one of a fixed number of threads.  *- * @par Thread Safety- * @e Distinct @e objects: Safe.@n- * @e Shared @e objects: Safe, with the specific exceptions of the join()- * wait() and notify_fork() functions. The join() and wait() functions must not- * be called at the same time as other calls to join() or wait() on the same- * pool. The notify_fork() function should not be called while any thread_pool- * function, or any function on an I/O object that is associated with the- * thread_pool, is being called in another thread. (In effect, this means that- * notify_fork() is safe only on a thread pool that has no internal or attached- * threads at the time.)- *  * @par Submitting tasks to the pool  *  * To submit functions to the thread pool, use the @ref asio::dispatch,@@ -95,67 +84,16 @@   /// Executor used to submit functions to a thread pool.   typedef basic_executor_type<std::allocator<void>, 0> executor_type; +  /// Scheduler used to schedule receivers on a thread pool.+  typedef basic_executor_type<std::allocator<void>, 0> scheduler_type;+ #if !defined(ASIO_NO_TS_EXECUTORS)   /// Constructs a pool with an automatically determined number of threads.   ASIO_DECL thread_pool();--  /// Constructs a pool with an automatically determined number of threads.-  /**-   * @param a An allocator that will be used for allocating objects that are-   * associated with the execution context, such as services and internal state-   * for I/O objects.-   */-  template <typename Allocator>-  thread_pool(allocator_arg_t, const Allocator& a); #endif // !defined(ASIO_NO_TS_EXECUTORS)    /// Constructs a pool with a specified number of threads.-  /**-   * @param num_threads The number of threads required.-   */-  ASIO_DECL explicit thread_pool(std::size_t num_threads);--  /// Constructs a pool with a specified number of threads.-  /**-   * @param num_threads The number of threads required.-   *-   * @param a An allocator that will be used for allocating objects that are-   * associated with the execution context, such as services and internal state-   * for I/O objects.-   */-  template <typename Allocator>-  thread_pool(allocator_arg_t, const Allocator& a, std::size_t num_threads);--  /// Constructs a pool with a specified number of threads.-  /**-   * Construct with a service maker, to create an initial set of services that-   * will be installed into the execution context at construction time.-   *-   * @param num_threads The number of threads required.-   *-   * @param initial_services Used to create the initial services. The @c make-   * function will be called once at the end of execution_context construction.-   */-  ASIO_DECL thread_pool(std::size_t num_threads,-      const execution_context::service_maker& initial_services);--  /// Constructs a pool with a specified number of threads.-  /**-   * Construct with a service maker, to create an initial set of services that-   * will be installed into the execution context at construction time.-   *-   * @param a An allocator that will be used for allocating objects that are-   * associated with the execution context, such as services and internal state-   * for I/O objects.-   *-   * @param num_threads The number of threads required.-   *-   * @param initial_services Used to create the initial services. The @c make-   * function will be called once at the end of execution_context construction.-   */-  template <typename Allocator>-  thread_pool(allocator_arg_t, const Allocator& a, std::size_t num_threads,-      const execution_context::service_maker& initial_services);+  ASIO_DECL thread_pool(std::size_t num_threads);    /// Destructor.   /**@@ -164,11 +102,14 @@   ASIO_DECL ~thread_pool();    /// Obtains the executor associated with the pool.-  executor_type get_executor() noexcept;+  executor_type get_executor() ASIO_NOEXCEPT;    /// Obtains the executor associated with the pool.-  executor_type executor() noexcept;+  executor_type executor() ASIO_NOEXCEPT; +  /// Obtains the scheduler associated with the pool.+  scheduler_type scheduler() ASIO_NOEXCEPT;+   /// Stops the threads.   /**    * This function stops the threads as soon as possible. As a result of calling@@ -197,39 +138,26 @@    * This function blocks until the threads in the pool have completed. If @c    * stop() is not called prior to @c wait(), the @c wait() call will wait    * until the pool has no more outstanding work.-   *-   * @note @c wait() is synonymous with @c join().    */   ASIO_DECL void wait();  private:-  thread_pool(const thread_pool&) = delete;-  thread_pool& operator=(const thread_pool&) = delete;+  thread_pool(const thread_pool&) ASIO_DELETED;+  thread_pool& operator=(const thread_pool&) ASIO_DELETED;    struct thread_function; -#if !defined(ASIO_NO_TS_EXECUTORS)-  // Helper function to calculate the default number of threads in the pool.-  ASIO_DECL static long default_thread_pool_size();-#endif // !defined(ASIO_NO_TS_EXECUTORS)--  // Helper function to ensure the thread pool size is not out of range.-  ASIO_DECL static long clamp_thread_pool_size(std::size_t n);--  // Helper function to start all threads in the pool.-  ASIO_DECL void start();+  // Helper function to create the underlying scheduler.+  ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s);    // The underlying scheduler.   detail::scheduler& scheduler_;    // The threads in the pool.-  detail::thread_group<allocator<void>> threads_;+  detail::thread_group threads_;    // The current number of threads in the pool.   detail::atomic_count num_threads_;--  // Whether a join call will have any effect.-  bool joinable_; };  /// Executor implementation type used to submit functions to a thread pool.@@ -237,8 +165,34 @@ class thread_pool::basic_executor_type : detail::thread_pool_bits { public:+#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated.) The sender type, when this type is used as a scheduler.+  typedef basic_executor_type sender_type;+#endif // !defined(ASIO_NO_DEPRECATED)++  /// The bulk execution shape type.+  typedef std::size_t shape_type;++  /// The bulk execution index type.+  typedef std::size_t index_type;++#if defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT) \+  && defined(ASIO_HAS_STD_EXCEPTION_PTR)+  template <+      template <typename...> class Tuple,+      template <typename...> class Variant>+  using value_types = Variant<Tuple<>>;++  template <template <typename...> class Variant>+  using error_types = Variant<std::exception_ptr>;++  ASIO_STATIC_CONSTEXPR(bool, sends_done = true);+#endif // defined(ASIO_HAS_DEDUCED_EXECUTION_IS_TYPED_SENDER_TRAIT)+       //   && defined(ASIO_HAS_STD_EXCEPTION_PTR)+   /// Copy constructor.-  basic_executor_type(const basic_executor_type& other) noexcept+  basic_executor_type(+      const basic_executor_type& other) ASIO_NOEXCEPT     : pool_(other.pool_),       allocator_(other.allocator_),       bits_(other.bits_)@@ -248,18 +202,20 @@         pool_->scheduler_.work_started();   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move constructor.-  basic_executor_type(basic_executor_type&& other) noexcept+  basic_executor_type(basic_executor_type&& other) ASIO_NOEXCEPT     : pool_(other.pool_),-      allocator_(static_cast<Allocator&&>(other.allocator_)),+      allocator_(ASIO_MOVE_CAST(Allocator)(other.allocator_)),       bits_(other.bits_)   {     if (Bits & outstanding_work_tracked)       other.pool_ = 0;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Destructor.-  ~basic_executor_type() noexcept+  ~basic_executor_type() ASIO_NOEXCEPT   {     if (Bits & outstanding_work_tracked)       if (pool_)@@ -267,10 +223,14 @@   }    /// Assignment operator.-  basic_executor_type& operator=(const basic_executor_type& other) noexcept;+  basic_executor_type& operator=(+      const basic_executor_type& other) ASIO_NOEXCEPT; +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move assignment operator.-  basic_executor_type& operator=(basic_executor_type&& other) noexcept;+  basic_executor_type& operator=(+      basic_executor_type&& other) ASIO_NOEXCEPT;+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)  #if !defined(GENERATING_DOCUMENTATION) private:@@ -288,7 +248,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::blocking.possibly); @endcode    */-  constexpr basic_executor_type<Allocator,+  ASIO_CONSTEXPR basic_executor_type<Allocator,       ASIO_UNSPECIFIED(Bits & ~blocking_mask)>   require(execution::blocking_t::possibly_t) const   {@@ -306,7 +266,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::blocking.always); @endcode    */-  constexpr basic_executor_type<Allocator,+  ASIO_CONSTEXPR basic_executor_type<Allocator,       ASIO_UNSPECIFIED((Bits & ~blocking_mask) | blocking_always)>   require(execution::blocking_t::always_t) const   {@@ -325,7 +285,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::blocking.never); @endcode    */-  constexpr basic_executor_type<Allocator,+  ASIO_CONSTEXPR basic_executor_type<Allocator,       ASIO_UNSPECIFIED(Bits & ~blocking_mask)>   require(execution::blocking_t::never_t) const   {@@ -343,7 +303,8 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::relationship.fork); @endcode    */-  constexpr basic_executor_type require(execution::relationship_t::fork_t) const+  ASIO_CONSTEXPR basic_executor_type require(+      execution::relationship_t::fork_t) const   {     return basic_executor_type(pool_,         allocator_, bits_ & ~relationship_continuation);@@ -359,7 +320,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::relationship.continuation); @endcode    */-  constexpr basic_executor_type require(+  ASIO_CONSTEXPR basic_executor_type require(       execution::relationship_t::continuation_t) const   {     return basic_executor_type(pool_,@@ -376,7 +337,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::outstanding_work.tracked); @endcode    */-  constexpr basic_executor_type<Allocator,+  ASIO_CONSTEXPR basic_executor_type<Allocator,       ASIO_UNSPECIFIED(Bits | outstanding_work_tracked)>   require(execution::outstanding_work_t::tracked_t) const   {@@ -394,7 +355,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::outstanding_work.untracked); @endcode    */-  constexpr basic_executor_type<Allocator,+  ASIO_CONSTEXPR basic_executor_type<Allocator,       ASIO_UNSPECIFIED(Bits & ~outstanding_work_tracked)>   require(execution::outstanding_work_t::untracked_t) const   {@@ -413,7 +374,7 @@    *     asio::execution::allocator(my_allocator)); @endcode    */   template <typename OtherAllocator>-  constexpr basic_executor_type<OtherAllocator, Bits>+  ASIO_CONSTEXPR basic_executor_type<OtherAllocator, Bits>   require(execution::allocator_t<OtherAllocator> a) const   {     return basic_executor_type<OtherAllocator, Bits>(@@ -430,7 +391,7 @@    * auto ex2 = asio::require(ex1,    *     asio::execution::allocator); @endcode    */-  constexpr basic_executor_type<std::allocator<void>, Bits>+  ASIO_CONSTEXPR basic_executor_type<std::allocator<void>, Bits>   require(execution::allocator_t<void>) const   {     return basic_executor_type<std::allocator<void>, Bits>(@@ -444,6 +405,25 @@   friend struct asio::execution::detail::outstanding_work_t<0>; #endif // !defined(GENERATING_DOCUMENTATION) +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated.) Query the current value of the @c bulk_guarantee property.+  /**+   * Do not call this function directly. It is intended for use with the+   * asio::query customisation point.+   *+   * For example:+   * @code auto ex = my_thread_pool.executor();+   * if (asio::query(ex, asio::execution::bulk_guarantee)+   *       == asio::execution::bulk_guarantee.parallel)+   *   ... @endcode+   */+  static ASIO_CONSTEXPR execution::bulk_guarantee_t query(+      execution::bulk_guarantee_t) ASIO_NOEXCEPT+  {+    return execution::bulk_guarantee.parallel;+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Query the current value of the @c mapping property.   /**    * Do not call this function directly. It is intended for use with the@@ -455,7 +435,8 @@    *       == asio::execution::mapping.thread)    *   ... @endcode    */-  static constexpr execution::mapping_t query(execution::mapping_t) noexcept+  static ASIO_CONSTEXPR execution::mapping_t query(+      execution::mapping_t) ASIO_NOEXCEPT   {     return execution::mapping.thread;   }@@ -470,7 +451,7 @@    * asio::thread_pool& pool = asio::query(    *     ex, asio::execution::context); @endcode    */-  thread_pool& query(execution::context_t) const noexcept+  thread_pool& query(execution::context_t) const ASIO_NOEXCEPT   {     return *pool_;   }@@ -486,7 +467,8 @@    *       == asio::execution::blocking.always)    *   ... @endcode    */-  constexpr execution::blocking_t query(execution::blocking_t) const noexcept+  ASIO_CONSTEXPR execution::blocking_t query(+      execution::blocking_t) const ASIO_NOEXCEPT   {     return (bits_ & blocking_never)       ? execution::blocking_t(execution::blocking.never)@@ -506,8 +488,8 @@    *       == asio::execution::relationship.continuation)    *   ... @endcode    */-  constexpr execution::relationship_t query(-      execution::relationship_t) const noexcept+  ASIO_CONSTEXPR execution::relationship_t query(+      execution::relationship_t) const ASIO_NOEXCEPT   {     return (bits_ & relationship_continuation)       ? execution::relationship_t(execution::relationship.continuation)@@ -525,8 +507,8 @@    *       == asio::execution::outstanding_work.tracked)    *   ... @endcode    */-  static constexpr execution::outstanding_work_t query(-      execution::outstanding_work_t) noexcept+  static ASIO_CONSTEXPR execution::outstanding_work_t query(+      execution::outstanding_work_t) ASIO_NOEXCEPT   {     return (Bits & outstanding_work_tracked)       ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -544,8 +526,8 @@    *     asio::execution::allocator); @endcode    */   template <typename OtherAllocator>-  constexpr Allocator query(-      execution::allocator_t<OtherAllocator>) const noexcept+  ASIO_CONSTEXPR Allocator query(+      execution::allocator_t<OtherAllocator>) const ASIO_NOEXCEPT   {     return allocator_;   }@@ -560,7 +542,8 @@    * auto alloc = asio::query(ex,    *     asio::execution::allocator); @endcode    */-  constexpr Allocator query(execution::allocator_t<void>) const noexcept+  ASIO_CONSTEXPR Allocator query(+      execution::allocator_t<void>) const ASIO_NOEXCEPT   {     return allocator_;   }@@ -575,7 +558,7 @@    * std::size_t occupancy = asio::query(    *     ex, asio::execution::occupancy); @endcode    */-  std::size_t query(execution::occupancy_t) const noexcept+  std::size_t query(execution::occupancy_t) const ASIO_NOEXCEPT   {     return static_cast<std::size_t>(pool_->num_threads_);   }@@ -586,14 +569,14 @@    * @return @c true if the current thread is running the thread pool. Otherwise    * returns @c false.    */-  bool running_in_this_thread() const noexcept;+  bool running_in_this_thread() const ASIO_NOEXCEPT;    /// Compare two executors for equality.   /**    * Two executors are equal if they refer to the same underlying thread pool.    */   friend bool operator==(const basic_executor_type& a,-      const basic_executor_type& b) noexcept+      const basic_executor_type& b) ASIO_NOEXCEPT   {     return a.pool_ == b.pool_       && a.allocator_ == b.allocator_@@ -605,7 +588,7 @@    * Two executors are equal if they refer to the same underlying thread pool.    */   friend bool operator!=(const basic_executor_type& a,-      const basic_executor_type& b) noexcept+      const basic_executor_type& b) ASIO_NOEXCEPT   {     return a.pool_ != b.pool_       || a.allocator_ != b.allocator_@@ -614,16 +597,58 @@    /// Execution function.   template <typename Function>-  void execute(Function&& f) const+  void execute(ASIO_MOVE_ARG(Function) f) const   {-    this->do_execute(static_cast<Function&&>(f),+    this->do_execute(ASIO_MOVE_CAST(Function)(f),         integral_constant<bool, (Bits & blocking_always) != 0>());   }  public:+#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated.) Bulk execution function.+  template <typename Function>+  void bulk_execute(ASIO_MOVE_ARG(Function) f, std::size_t n) const+  {+    this->do_bulk_execute(ASIO_MOVE_CAST(Function)(f), n,+        integral_constant<bool, (Bits & blocking_always) != 0>());+  }++  /// (Deprecated.) Schedule function.+  /**+   * Do not call this function directly. It is intended for use with the+   * execution::schedule customisation point.+   *+   * @return An object that satisfies the sender concept.+   */+  sender_type schedule() const ASIO_NOEXCEPT+  {+    return *this;+  }++  /// (Deprecated.) Connect function.+  /**+   * Do not call this function directly. It is intended for use with the+   * execution::connect customisation point.+   *+   * @return An object of an unspecified type that satisfies the @c+   * operation_state concept.+   */+  template <ASIO_EXECUTION_RECEIVER_OF_0 Receiver>+#if defined(GENERATING_DOCUMENTATION)+  unspecified+#else // defined(GENERATING_DOCUMENTATION)+  execution::detail::as_operation<basic_executor_type, Receiver>+#endif // defined(GENERATING_DOCUMENTATION)+  connect(ASIO_MOVE_ARG(Receiver) r) const+  {+    return execution::detail::as_operation<basic_executor_type, Receiver>(+        *this, ASIO_MOVE_CAST(Receiver)(r));+  }+#endif // !defined(ASIO_NO_DEPRECATED)+ #if !defined(ASIO_NO_TS_EXECUTORS)   /// Obtain the underlying execution context.-  thread_pool& context() const noexcept;+  thread_pool& context() const ASIO_NOEXCEPT;    /// Inform the thread pool that it has some outstanding work to do.   /**@@ -631,7 +656,7 @@    * This ensures that the thread pool's join() function will not return while    * the work is underway.    */-  void on_work_started() const noexcept;+  void on_work_started() const ASIO_NOEXCEPT;    /// Inform the thread pool that some work is no longer outstanding.   /**@@ -639,7 +664,7 @@    * finished. Once the count of unfinished work reaches zero, the thread    * pool's join() function is permitted to exit.    */-  void on_work_finished() const noexcept;+  void on_work_finished() const ASIO_NOEXCEPT;    /// Request the thread pool to invoke the given function object.   /**@@ -656,7 +681,8 @@    * internal storage needed for function invocation.    */   template <typename Function, typename OtherAllocator>-  void dispatch(Function&& f, const OtherAllocator& a) const;+  void dispatch(ASIO_MOVE_ARG(Function) f,+      const OtherAllocator& a) const;    /// Request the thread pool to invoke the given function object.   /**@@ -672,7 +698,8 @@    * internal storage needed for function invocation.    */   template <typename Function, typename OtherAllocator>-  void post(Function&& f, const OtherAllocator& a) const;+  void post(ASIO_MOVE_ARG(Function) f,+      const OtherAllocator& a) const;    /// Request the thread pool to invoke the given function object.   /**@@ -692,7 +719,8 @@    * internal storage needed for function invocation.    */   template <typename Function, typename OtherAllocator>-  void defer(Function&& f, const OtherAllocator& a) const;+  void defer(ASIO_MOVE_ARG(Function) f,+      const OtherAllocator& a) const; #endif // !defined(ASIO_NO_TS_EXECUTORS)  private:@@ -700,7 +728,7 @@   template <typename, unsigned int> friend class basic_executor_type;    // Constructor used by thread_pool::get_executor().-  explicit basic_executor_type(thread_pool& p) noexcept+  explicit basic_executor_type(thread_pool& p) ASIO_NOEXCEPT     : pool_(&p),       allocator_(),       bits_(0)@@ -711,7 +739,7 @@    // Constructor used by require().   basic_executor_type(thread_pool* p,-      const Allocator& a, unsigned int bits) noexcept+      const Allocator& a, unsigned int bits) ASIO_NOEXCEPT     : pool_(p),       allocator_(a),       bits_(bits)@@ -723,12 +751,22 @@    /// Execution helper implementation for possibly and never blocking.   template <typename Function>-  void do_execute(Function&& f, false_type) const;+  void do_execute(ASIO_MOVE_ARG(Function) f, false_type) const;    /// Execution helper implementation for always blocking.   template <typename Function>-  void do_execute(Function&& f, true_type) const;+  void do_execute(ASIO_MOVE_ARG(Function) f, true_type) const; +  /// Bulk execution helper implementation for possibly and never blocking.+  template <typename Function>+  void do_bulk_execute(ASIO_MOVE_ARG(Function) f,+      std::size_t n, false_type) const;++  /// Bulk execution helper implementation for always blocking.+  template <typename Function>+  void do_bulk_execute(ASIO_MOVE_ARG(Function) f,+      std::size_t n, true_type) const;+   // The underlying thread pool.   thread_pool* pool_; @@ -750,8 +788,8 @@     asio::thread_pool::basic_executor_type<Allocator, Bits>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true); };  #endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -764,13 +802,53 @@     Function   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef void result_type; };  #endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) +#if !defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++#if !defined(ASIO_NO_DEPRECATED)++template <typename Allocator, unsigned int Bits>+struct schedule_member<+    const asio::thread_pool::basic_executor_type<Allocator, Bits>+  >+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef asio::thread_pool::basic_executor_type<+      Allocator, Bits> result_type;+};++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // !defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++#if !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++#if !defined(ASIO_NO_DEPRECATED)++template <typename Allocator, unsigned int Bits, typename Receiver>+struct connect_member<+    const asio::thread_pool::basic_executor_type<Allocator, Bits>,+    Receiver+  >+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+  typedef asio::execution::detail::as_operation<+      asio::thread_pool::basic_executor_type<Allocator, Bits>,+      Receiver> result_type;+};++#endif // !defined(ASIO_NO_DEPRECATED)++#endif // !defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)+ #if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)  template <typename Allocator, unsigned int Bits>@@ -779,8 +857,8 @@     asio::execution::blocking_t::possibly_t   > : asio::detail::thread_pool_bits {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::thread_pool::basic_executor_type<       Allocator, Bits & ~blocking_mask> result_type; };@@ -791,8 +869,8 @@     asio::execution::blocking_t::always_t   > : asio::detail::thread_pool_bits {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::thread_pool::basic_executor_type<Allocator,       (Bits & ~blocking_mask) | blocking_always> result_type; };@@ -803,8 +881,8 @@     asio::execution::blocking_t::never_t   > : asio::detail::thread_pool_bits {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::thread_pool::basic_executor_type<       Allocator, Bits & ~blocking_mask> result_type; };@@ -815,8 +893,8 @@     asio::execution::relationship_t::fork_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::thread_pool::basic_executor_type<       Allocator, Bits> result_type; };@@ -827,8 +905,8 @@     asio::execution::relationship_t::continuation_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::thread_pool::basic_executor_type<       Allocator, Bits> result_type; };@@ -839,8 +917,8 @@     asio::execution::outstanding_work_t::tracked_t   > : asio::detail::thread_pool_bits {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::thread_pool::basic_executor_type<       Allocator, Bits | outstanding_work_tracked> result_type; };@@ -851,8 +929,8 @@     asio::execution::outstanding_work_t::untracked_t   > : asio::detail::thread_pool_bits {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::thread_pool::basic_executor_type<       Allocator, Bits & ~outstanding_work_tracked> result_type; };@@ -863,8 +941,8 @@     asio::execution::allocator_t<void>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::thread_pool::basic_executor_type<       std::allocator<void>, Bits> result_type; };@@ -876,8 +954,8 @@     asio::execution::allocator_t<OtherAllocator>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);   typedef asio::thread_pool::basic_executor_type<       OtherAllocator, Bits> result_type; };@@ -886,6 +964,8 @@  #if !defined(ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT) +#if !defined(ASIO_NO_DEPRECATED)+ template <typename Allocator, unsigned int Bits, typename Property> struct query_static_constexpr_member<     asio::thread_pool::basic_executor_type<Allocator, Bits>,@@ -893,16 +973,40 @@     typename asio::enable_if<       asio::is_convertible<         Property,+        asio::execution::bulk_guarantee_t+      >::value+    >::type+  >+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);+  typedef asio::execution::bulk_guarantee_t::parallel_t result_type;++  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT+  {+    return result_type();+  }+};++#endif // !defined(ASIO_NO_DEPRECATED)++template <typename Allocator, unsigned int Bits, typename Property>+struct query_static_constexpr_member<+    asio::thread_pool::basic_executor_type<Allocator, Bits>,+    Property,+    typename asio::enable_if<+      asio::is_convertible<+        Property,         asio::execution::outstanding_work_t       >::value     >::type   > : asio::detail::thread_pool_bits {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::outstanding_work_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return (Bits & outstanding_work_tracked)       ? execution::outstanding_work_t(execution::outstanding_work.tracked)@@ -922,11 +1026,11 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::mapping_t::thread_t result_type; -  static constexpr result_type value() noexcept+  static ASIO_CONSTEXPR result_type value() ASIO_NOEXCEPT   {     return result_type();   }@@ -948,8 +1052,8 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::blocking_t result_type; }; @@ -965,8 +1069,8 @@     >::type   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::execution::relationship_t result_type; }; @@ -976,8 +1080,8 @@     asio::execution::occupancy_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef std::size_t result_type; }; @@ -987,8 +1091,8 @@     asio::execution::context_t   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef asio::thread_pool& result_type; }; @@ -998,8 +1102,8 @@     asio::execution::allocator_t<void>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef Allocator result_type; }; @@ -1009,8 +1113,8 @@     asio::execution::allocator_t<OtherAllocator>   > {-  static constexpr bool is_valid = true;-  static constexpr bool is_noexcept = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);   typedef Allocator result_type; }; 
link/modules/asio-standalone/asio/include/asio/time_traits.hpp view
@@ -2,7 +2,7 @@ // time_traits.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -17,8 +17,6 @@  #include "asio/detail/socket_types.hpp" // Must come before posix_time. -#if !defined(ASIO_NO_DEPRECATED)- #if defined(ASIO_HAS_BOOST_DATE_TIME) \   || defined(GENERATING_DOCUMENTATION) @@ -28,11 +26,11 @@  namespace asio { -/// (Deprecated) Time traits suitable for use with the deadline timer.+/// Time traits suitable for use with the deadline timer. template <typename Time> struct time_traits; -/// (Deprecated) Time traits specialised for posix_time.+/// Time traits specialised for posix_time. template <> struct time_traits<boost::posix_time::ptime> {@@ -84,7 +82,5 @@  #endif // defined(ASIO_HAS_BOOST_DATE_TIME)        // || defined(GENERATING_DOCUMENTATION)--#endif // !defined(ASIO_NO_DEPRECATED)  #endif // ASIO_TIME_TRAITS_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/bulk_execute_free.hpp view
@@ -0,0 +1,114 @@+//+// traits/bulk_execute_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_BULK_EXECUTE_FREE_HPP+#define ASIO_TRAITS_BULK_EXECUTE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_BULK_EXECUTE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_free_default;++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_free;++} // namespace traits+namespace detail {++struct no_bulk_execute_free+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_FREE_TRAIT)++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_free_trait : no_bulk_execute_free+{+};++template <typename T, typename F, typename N>+struct bulk_execute_free_trait<T, F, N,+  typename void_type<+    decltype(bulk_execute(declval<T>(), declval<F>(), declval<N>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    bulk_execute(declval<T>(), declval<F>(), declval<N>()));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    bulk_execute(declval<T>(), declval<F>(), declval<N>())));+};++#else // defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_FREE_TRAIT)++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_free_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value+      && is_same<F, typename decay<F>::type>::value+      && is_same<N, typename decay<N>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_bulk_execute_free,+      traits::bulk_execute_free<typename add_const<T>::type, F, N>+    >::type,+    traits::bulk_execute_free<+      typename remove_reference<T>::type,+      typename decay<F>::type,+      typename decay<N>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename F, typename N, typename>+struct bulk_execute_free_default :+  detail::bulk_execute_free_trait<T, F, N>+{+};++template <typename T, typename F, typename N, typename>+struct bulk_execute_free :+  bulk_execute_free_default<T, F, N>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_BULK_EXECUTE_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/bulk_execute_member.hpp view
@@ -0,0 +1,114 @@+//+// traits/bulk_execute_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_BULK_EXECUTE_MEMBER_HPP+#define ASIO_TRAITS_BULK_EXECUTE_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_BULK_EXECUTE_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_member_default;++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_member;++} // namespace traits+namespace detail {++struct no_bulk_execute_member+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_MEMBER_TRAIT)++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_member_trait : no_bulk_execute_member+{+};++template <typename T, typename F, typename N>+struct bulk_execute_member_trait<T, F, N,+  typename void_type<+    decltype(declval<T>().bulk_execute(declval<F>(), declval<N>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    declval<T>().bulk_execute(declval<F>(), declval<N>()));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<T>().bulk_execute(declval<F>(), declval<N>())));+};++#else // defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_MEMBER_TRAIT)++template <typename T, typename F, typename N, typename = void>+struct bulk_execute_member_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value+      && is_same<F, typename decay<F>::type>::value+      && is_same<N, typename decay<N>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_bulk_execute_member,+      traits::bulk_execute_member<typename add_const<T>::type, F, N>+    >::type,+    traits::bulk_execute_member<+      typename remove_reference<T>::type,+      typename decay<F>::type,+      typename decay<N>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_BULK_EXECUTE_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename F, typename N, typename>+struct bulk_execute_member_default :+  detail::bulk_execute_member_trait<T, F, N>+{+};++template <typename T, typename F, typename N, typename>+struct bulk_execute_member :+  bulk_execute_member_default<T, F, N>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_BULK_EXECUTE_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/connect_free.hpp view
@@ -0,0 +1,112 @@+//+// traits/connect_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_CONNECT_FREE_HPP+#define ASIO_TRAITS_CONNECT_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename S, typename R, typename = void>+struct connect_free_default;++template <typename S, typename R, typename = void>+struct connect_free;++} // namespace traits+namespace detail {++struct no_connect_free+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)++template <typename S, typename R, typename = void>+struct connect_free_trait : no_connect_free+{+};++template <typename S, typename R>+struct connect_free_trait<S, R,+  typename void_type<+    decltype(connect(declval<S>(), declval<R>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    connect(declval<S>(), declval<R>()));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    connect(declval<S>(), declval<R>())));+};++#else // defined(ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)++template <typename S, typename R, typename = void>+struct connect_free_trait :+  conditional<+    is_same<S, typename remove_reference<S>::type>::value+      && is_same<R, typename decay<R>::type>::value,+    typename conditional<+      is_same<S, typename add_const<S>::type>::value,+      no_connect_free,+      traits::connect_free<typename add_const<S>::type, R>+    >::type,+    traits::connect_free<+      typename remove_reference<S>::type,+      typename decay<R>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_CONNECT_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename S, typename R, typename>+struct connect_free_default :+  detail::connect_free_trait<S, R>+{+};++template <typename S, typename R, typename>+struct connect_free :+  connect_free_default<S, R>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_CONNECT_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/connect_member.hpp view
@@ -0,0 +1,112 @@+//+// traits/connect_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_CONNECT_MEMBER_HPP+#define ASIO_TRAITS_CONNECT_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename S, typename R, typename = void>+struct connect_member_default;++template <typename S, typename R, typename = void>+struct connect_member;++} // namespace traits+namespace detail {++struct no_connect_member+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++template <typename S, typename R, typename = void>+struct connect_member_trait : no_connect_member+{+};++template <typename S, typename R>+struct connect_member_trait<S, R,+  typename void_type<+    decltype(declval<S>().connect(declval<R>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    declval<S>().connect(declval<R>()));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<S>().connect(declval<R>())));+};++#else // defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++template <typename S, typename R, typename = void>+struct connect_member_trait :+  conditional<+    is_same<S, typename remove_reference<S>::type>::value+      && is_same<R, typename decay<R>::type>::value,+    typename conditional<+      is_same<S, typename add_const<S>::type>::value,+      no_connect_member,+      traits::connect_member<typename add_const<S>::type, R>+    >::type,+    traits::connect_member<+      typename remove_reference<S>::type,+      typename decay<R>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_CONNECT_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename S, typename R, typename>+struct connect_member_default :+  detail::connect_member_trait<S, R>+{+};++template <typename S, typename R, typename>+struct connect_member :+  connect_member_default<S, R>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_CONNECT_MEMBER_HPP
link/modules/asio-standalone/asio/include/asio/traits/equality_comparable.hpp view
@@ -2,7 +2,7 @@ // traits/equality_comparable.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  namespace asio { namespace traits {@@ -36,8 +40,8 @@  struct no_equality_comparable {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)@@ -49,7 +53,7 @@  template <typename T> struct equality_comparable_trait<T,-  void_t<+  typename void_type<     decltype(       static_cast<void>(         static_cast<bool>(declval<const T>() == declval<const T>())@@ -58,24 +62,24 @@         static_cast<bool>(declval<const T>() != declval<const T>())       )     )-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true); -  static constexpr bool is_noexcept =+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =     noexcept(declval<const T>() == declval<const T>())-      && noexcept(declval<const T>() != declval<const T>());+      && noexcept(declval<const T>() != declval<const T>())); };  #else // defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)  template <typename T, typename = void> struct equality_comparable_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value,     no_equality_comparable,-    traits::equality_comparable<decay_t<T>>-  >+    traits::equality_comparable<typename decay<T>::type>+  >::type { }; 
+ link/modules/asio-standalone/asio/include/asio/traits/execute_free.hpp view
@@ -0,0 +1,108 @@+//+// traits/execute_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_EXECUTE_FREE_HPP+#define ASIO_TRAITS_EXECUTE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename F, typename = void>+struct execute_free_default;++template <typename T, typename F, typename = void>+struct execute_free;++} // namespace traits+namespace detail {++struct no_execute_free+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)++template <typename T, typename F, typename = void>+struct execute_free_trait : no_execute_free+{+};++template <typename T, typename F>+struct execute_free_trait<T, F,+  typename void_type<+    decltype(execute(declval<T>(), declval<F>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    execute(declval<T>(), declval<F>()));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    execute(declval<T>(), declval<F>())));+};++#else // defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)++template <typename T, typename F, typename = void>+struct execute_free_trait :+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<F, typename decay<F>::type>::value,+    no_execute_free,+    traits::execute_free<+      typename decay<T>::type,+      typename decay<F>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_EXECUTE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename F, typename>+struct execute_free_default :+  detail::execute_free_trait<T, F>+{+};++template <typename T, typename F, typename>+struct execute_free :+  execute_free_default<T, F>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_EXECUTE_FREE_HPP
link/modules/asio-standalone/asio/include/asio/traits/execute_member.hpp view
@@ -2,7 +2,7 @@ // traits/execute_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@  struct no_execute_member {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)@@ -51,31 +55,31 @@  template <typename T, typename F> struct execute_member_trait<T, F,-  void_t<+  typename void_type<     decltype(declval<T>().execute(declval<F>()))-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(     declval<T>().execute(declval<F>())); -  static constexpr bool is_noexcept =-    noexcept(declval<T>().execute(declval<F>()));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<T>().execute(declval<F>()))); };  #else // defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)  template <typename T, typename F, typename = void> struct execute_member_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<F, decay_t<F>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<F, typename decay<F>::type>::value,     no_execute_member,     traits::execute_member<-      decay_t<T>,-      decay_t<F>>-  >+      typename decay<T>::type,+      typename decay<F>::type>+  >::type { }; 
link/modules/asio-standalone/asio/include/asio/traits/prefer_free.hpp view
@@ -2,7 +2,7 @@ // traits/prefer_free.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@  struct no_prefer_free {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)@@ -51,31 +55,31 @@  template <typename T, typename Property> struct prefer_free_trait<T, Property,-  void_t<+  typename void_type<     decltype(prefer(declval<T>(), declval<Property>()))-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(     prefer(declval<T>(), declval<Property>())); -  static constexpr bool is_noexcept =-    noexcept(prefer(declval<T>(), declval<Property>()));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    prefer(declval<T>(), declval<Property>()))); };  #else // defined(ASIO_HAS_DEDUCED_PREFER_FREE_TRAIT)  template <typename T, typename Property, typename = void> struct prefer_free_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_prefer_free,     traits::prefer_free<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; 
link/modules/asio-standalone/asio/include/asio/traits/prefer_member.hpp view
@@ -2,7 +2,7 @@ // traits/prefer_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@  struct no_prefer_member {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)@@ -51,31 +55,31 @@  template <typename T, typename Property> struct prefer_member_trait<T, Property,-  void_t<+  typename void_type<     decltype(declval<T>().prefer(declval<Property>()))-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(     declval<T>().prefer(declval<Property>())); -  static constexpr bool is_noexcept =-    noexcept(declval<T>().prefer(declval<Property>()));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<T>().prefer(declval<Property>()))); };  #else // defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT)  template <typename T, typename Property, typename = void> struct prefer_member_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_prefer_member,     traits::prefer_member<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; 
link/modules/asio-standalone/asio/include/asio/traits/query_free.hpp view
@@ -2,7 +2,7 @@ // traits/query_free.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@  struct no_query_free {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)@@ -51,31 +55,31 @@  template <typename T, typename Property> struct query_free_trait<T, Property,-  void_t<+  typename void_type<     decltype(query(declval<T>(), declval<Property>()))-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(     query(declval<T>(), declval<Property>())); -  static constexpr bool is_noexcept =-    noexcept(query(declval<T>(), declval<Property>()));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    query(declval<T>(), declval<Property>()))); };  #else // defined(ASIO_HAS_DEDUCED_QUERY_FREE_TRAIT)  template <typename T, typename Property, typename = void> struct query_free_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_query_free,     traits::query_free<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; 
link/modules/asio-standalone/asio/include/asio/traits/query_member.hpp view
@@ -2,7 +2,7 @@ // traits/query_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@  struct no_query_member {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)@@ -51,31 +55,31 @@  template <typename T, typename Property> struct query_member_trait<T, Property,-  void_t<+  typename void_type<     decltype(declval<T>().query(declval<Property>()))-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(     declval<T>().query(declval<Property>())); -  static constexpr bool is_noexcept =-    noexcept(declval<T>().query(declval<Property>()));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<T>().query(declval<Property>()))); };  #else // defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT)  template <typename T, typename Property, typename = void> struct query_member_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_query_member,     traits::query_member<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; 
link/modules/asio-standalone/asio/include/asio/traits/query_static_constexpr_member.hpp view
@@ -2,7 +2,7 @@ // traits/query_static_constexpr_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,10 +18,16 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE) \+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_CONSTEXPR) \+  && defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE) \   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_CONSTEXPR)+       //   && defined(ASIO_HAS_CONSTANT_EXPRESSION_SFINAE)        //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp"@@ -40,19 +46,19 @@  struct no_query_static_constexpr_member {-  static constexpr bool is_valid = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false); };  template <typename T, typename Property, typename = void> struct query_static_constexpr_member_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_query_static_constexpr_member,     traits::query_static_constexpr_member<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; @@ -60,17 +66,18 @@  template <typename T, typename Property> struct query_static_constexpr_member_trait<T, Property,-  enable_if_t<+  typename enable_if<     (static_cast<void>(T::query(Property{})), true)-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(T::query(Property{})); -  static constexpr bool is_noexcept = noexcept(T::query(Property{}));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    noexcept(T::query(Property{}))); -  static constexpr result_type value() noexcept(is_noexcept)+  static ASIO_CONSTEXPR result_type value() noexcept(is_noexcept)   {     return T::query(Property{});   }
link/modules/asio-standalone/asio/include/asio/traits/require_concept_free.hpp view
@@ -2,7 +2,7 @@ // traits/require_concept_free.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_FREE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@  struct no_require_concept_free {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_FREE_TRAIT)@@ -51,31 +55,31 @@  template <typename T, typename Property> struct require_concept_free_trait<T, Property,-  void_t<+  typename void_type<     decltype(require_concept(declval<T>(), declval<Property>()))-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(     require_concept(declval<T>(), declval<Property>())); -  static constexpr bool is_noexcept =-    noexcept(require_concept(declval<T>(), declval<Property>()));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    require_concept(declval<T>(), declval<Property>()))); };  #else // defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_FREE_TRAIT)  template <typename T, typename Property, typename = void> struct require_concept_free_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_require_concept_free,     traits::require_concept_free<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; 
link/modules/asio-standalone/asio/include/asio/traits/require_concept_member.hpp view
@@ -2,7 +2,7 @@ // traits/require_concept_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@  struct no_require_concept_member {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)@@ -51,31 +55,31 @@  template <typename T, typename Property> struct require_concept_member_trait<T, Property,-  void_t<+  typename void_type<     decltype(declval<T>().require_concept(declval<Property>()))-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(     declval<T>().require_concept(declval<Property>())); -  static constexpr bool is_noexcept =-    noexcept(declval<T>().require_concept(declval<Property>()));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<T>().require_concept(declval<Property>()))); };  #else // defined(ASIO_HAS_DEDUCED_REQUIRE_CONCEPT_MEMBER_TRAIT)  template <typename T, typename Property, typename = void> struct require_concept_member_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_require_concept_member,     traits::require_concept_member<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; 
link/modules/asio-standalone/asio/include/asio/traits/require_free.hpp view
@@ -2,7 +2,7 @@ // traits/require_free.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@  struct no_require_free {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)@@ -51,31 +55,31 @@  template <typename T, typename Property> struct require_free_trait<T, Property,-  void_t<+  typename void_type<     decltype(require(declval<T>(), declval<Property>()))-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(     require(declval<T>(), declval<Property>())); -  static constexpr bool is_noexcept =-    noexcept(require(declval<T>(), declval<Property>()));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    require(declval<T>(), declval<Property>()))); };  #else // defined(ASIO_HAS_DEDUCED_REQUIRE_FREE_TRAIT)  template <typename T, typename Property, typename = void> struct require_free_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_require_free,     traits::require_free<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; 
link/modules/asio-standalone/asio/include/asio/traits/require_member.hpp view
@@ -2,7 +2,7 @@ // traits/require_member.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,9 +18,13 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT 1-#endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp" @@ -38,8 +42,8 @@  struct no_require_member {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  #if defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)@@ -51,31 +55,31 @@  template <typename T, typename Property> struct require_member_trait<T, Property,-  void_t<+  typename void_type<     decltype(declval<T>().require(declval<Property>()))-  >>+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(     declval<T>().require(declval<Property>())); -  static constexpr bool is_noexcept =-    noexcept(declval<T>().require(declval<Property>()));+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<T>().require(declval<Property>()))); };  #else // defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)  template <typename T, typename Property, typename = void> struct require_member_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_require_member,     traits::require_member<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; 
+ link/modules/asio-standalone/asio/include/asio/traits/schedule_free.hpp view
@@ -0,0 +1,108 @@+//+// traits/schedule_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SCHEDULE_FREE_HPP+#define ASIO_TRAITS_SCHEDULE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct schedule_free_default;++template <typename T, typename = void>+struct schedule_free;++} // namespace traits+namespace detail {++struct no_schedule_free+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)++template <typename T, typename = void>+struct schedule_free_trait : no_schedule_free+{+};++template <typename T>+struct schedule_free_trait<T,+  typename void_type<+    decltype(schedule(declval<T>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(schedule(declval<T>()));++  ASIO_STATIC_CONSTEXPR(bool,+    is_noexcept = noexcept(schedule(declval<T>())));+};++#else // defined(ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)++template <typename T, typename = void>+struct schedule_free_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_schedule_free,+      traits::schedule_free<typename add_const<T>::type>+    >::type,+    traits::schedule_free<typename remove_reference<T>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SCHEDULE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct schedule_free_default :+  detail::schedule_free_trait<T>+{+};++template <typename T, typename>+struct schedule_free :+  schedule_free_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SCHEDULE_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/schedule_member.hpp view
@@ -0,0 +1,108 @@+//+// traits/schedule_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SCHEDULE_MEMBER_HPP+#define ASIO_TRAITS_SCHEDULE_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct schedule_member_default;++template <typename T, typename = void>+struct schedule_member;++} // namespace traits+namespace detail {++struct no_schedule_member+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++template <typename T, typename = void>+struct schedule_member_trait : no_schedule_member+{+};++template <typename T>+struct schedule_member_trait<T,+  typename void_type<+    decltype(declval<T>().schedule())+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(declval<T>().schedule());++  ASIO_STATIC_CONSTEXPR(bool,+    is_noexcept = noexcept(declval<T>().schedule()));+};++#else // defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++template <typename T, typename = void>+struct schedule_member_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_schedule_member,+      traits::schedule_member<typename add_const<T>::type>+    >::type,+    traits::schedule_member<typename remove_reference<T>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SCHEDULE_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct schedule_member_default :+  detail::schedule_member_trait<T>+{+};++template <typename T, typename>+struct schedule_member :+  schedule_member_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SCHEDULE_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_done_free.hpp view
@@ -0,0 +1,108 @@+//+// traits/set_done_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SET_DONE_FREE_HPP+#define ASIO_TRAITS_SET_DONE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct set_done_free_default;++template <typename T, typename = void>+struct set_done_free;++} // namespace traits+namespace detail {++struct no_set_done_free+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)++template <typename T, typename = void>+struct set_done_free_trait : no_set_done_free+{+};++template <typename T>+struct set_done_free_trait<T,+  typename void_type<+    decltype(set_done(declval<T>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(set_done(declval<T>()));++  ASIO_STATIC_CONSTEXPR(bool,+    is_noexcept = noexcept(set_done(declval<T>())));+};++#else // defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)++template <typename T, typename = void>+struct set_done_free_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_set_done_free,+      traits::set_done_free<typename add_const<T>::type>+    >::type,+    traits::set_done_free<typename remove_reference<T>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SET_DONE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct set_done_free_default :+  detail::set_done_free_trait<T>+{+};++template <typename T, typename>+struct set_done_free :+  set_done_free_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_DONE_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_done_member.hpp view
@@ -0,0 +1,108 @@+//+// traits/set_done_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SET_DONE_MEMBER_HPP+#define ASIO_TRAITS_SET_DONE_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct set_done_member_default;++template <typename T, typename = void>+struct set_done_member;++} // namespace traits+namespace detail {++struct no_set_done_member+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename T, typename = void>+struct set_done_member_trait : no_set_done_member+{+};++template <typename T>+struct set_done_member_trait<T,+  typename void_type<+    decltype(declval<T>().set_done())+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(declval<T>().set_done());++  ASIO_STATIC_CONSTEXPR(bool,+    is_noexcept = noexcept(declval<T>().set_done()));+};++#else // defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++template <typename T, typename = void>+struct set_done_member_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_set_done_member,+      traits::set_done_member<typename add_const<T>::type>+    >::type,+    traits::set_done_member<typename remove_reference<T>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SET_DONE_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct set_done_member_default :+  detail::set_done_member_trait<T>+{+};++template <typename T, typename>+struct set_done_member :+  set_done_member_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_DONE_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_error_free.hpp view
@@ -0,0 +1,112 @@+//+// traits/set_error_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SET_ERROR_FREE_HPP+#define ASIO_TRAITS_SET_ERROR_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename E, typename = void>+struct set_error_free_default;++template <typename T, typename E, typename = void>+struct set_error_free;++} // namespace traits+namespace detail {++struct no_set_error_free+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)++template <typename T, typename E, typename = void>+struct set_error_free_trait : no_set_error_free+{+};++template <typename T, typename E>+struct set_error_free_trait<T, E,+  typename void_type<+    decltype(set_error(declval<T>(), declval<E>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    set_error(declval<T>(), declval<E>()));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    set_error(declval<T>(), declval<E>())));+};++#else // defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)++template <typename T, typename E, typename = void>+struct set_error_free_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value+      && is_same<E, typename decay<E>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_set_error_free,+      traits::set_error_free<typename add_const<T>::type, E>+    >::type,+    traits::set_error_free<+      typename remove_reference<T>::type,+      typename decay<E>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SET_ERROR_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename E, typename>+struct set_error_free_default :+  detail::set_error_free_trait<T, E>+{+};++template <typename T, typename E, typename>+struct set_error_free :+  set_error_free_default<T, E>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_ERROR_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_error_member.hpp view
@@ -0,0 +1,112 @@+//+// traits/set_error_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SET_ERROR_MEMBER_HPP+#define ASIO_TRAITS_SET_ERROR_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename E, typename = void>+struct set_error_member_default;++template <typename T, typename E, typename = void>+struct set_error_member;++} // namespace traits+namespace detail {++struct no_set_error_member+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename T, typename E, typename = void>+struct set_error_member_trait : no_set_error_member+{+};++template <typename T, typename E>+struct set_error_member_trait<T, E,+  typename void_type<+    decltype(declval<T>().set_error(declval<E>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    declval<T>().set_error(declval<E>()));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<T>().set_error(declval<E>())));+};++#else // defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++template <typename T, typename E, typename = void>+struct set_error_member_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value+      && is_same<E, typename decay<E>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_set_error_member,+      traits::set_error_member<typename add_const<T>::type, E>+    >::type,+    traits::set_error_member<+      typename remove_reference<T>::type,+      typename decay<E>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SET_ERROR_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename E, typename>+struct set_error_member_default :+  detail::set_error_member_trait<T, E>+{+};++template <typename T, typename E, typename>+struct set_error_member :+  set_error_member_default<T, E>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_ERROR_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_value_free.hpp view
@@ -0,0 +1,234 @@+//+// traits/set_value_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SET_VALUE_FREE_HPP+#define ASIO_TRAITS_SET_VALUE_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename Vs, typename = void>+struct set_value_free_default;++template <typename T, typename Vs, typename = void>+struct set_value_free;++} // namespace traits+namespace detail {++struct no_set_value_free+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)++template <typename T, typename Vs, typename = void>+struct set_value_free_trait : no_set_value_free+{+};++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Vs>+struct set_value_free_trait<T, void(Vs...),+  typename void_type<+    decltype(set_value(declval<T>(), declval<Vs>()...))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    set_value(declval<T>(), declval<Vs>()...));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    set_value(declval<T>(), declval<Vs>()...)));+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct set_value_free_trait<T, void(),+  typename void_type<+    decltype(set_value(declval<T>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(set_value(declval<T>()));++  ASIO_STATIC_CONSTEXPR(bool,+    is_noexcept = noexcept(set_value(declval<T>())));+};++#define ASIO_PRIVATE_SET_VALUE_FREE_TRAIT_DEF(n) \+  template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+  struct set_value_free_trait<T, void(ASIO_VARIADIC_TARGS(n)), \+    typename void_type< \+      decltype(set_value(declval<T>(), ASIO_VARIADIC_DECLVAL(n))) \+    >::type> \+  { \+    ASIO_STATIC_CONSTEXPR(bool, is_valid = true); \+  \+    using result_type = decltype( \+      set_value(declval<T>(), ASIO_VARIADIC_DECLVAL(n))); \+  \+    ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept( \+      set_value(declval<T>(), ASIO_VARIADIC_DECLVAL(n)))); \+  }; \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_FREE_TRAIT_DEF)+#undef ASIO_PRIVATE_SET_VALUE_FREE_TRAIT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#else // defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)++template <typename T, typename Vs, typename = void>+struct set_value_free_trait;++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Vs>+struct set_value_free_trait<T, void(Vs...)> :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value+      && conjunction<is_same<Vs, typename decay<Vs>::type>...>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_set_value_free,+      traits::set_value_free<typename add_const<T>::type, void(Vs...)>+    >::type,+    traits::set_value_free<+      typename remove_reference<T>::type,+      void(typename decay<Vs>::type...)>+  >::type+{+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct set_value_free_trait<T, void()> :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_set_value_free,+      traits::set_value_free<typename add_const<T>::type, void()>+    >::type,+    traits::set_value_free<typename remove_reference<T>::type, void()>+  >::type+{+};++#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME(n) \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_##n++#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1 \+  && is_same<T1, typename decay<T1>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1 \+  && is_same<T2, typename decay<T2>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2 \+  && is_same<T3, typename decay<T3>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3 \+  && is_same<T4, typename decay<T4>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4 \+  && is_same<T5, typename decay<T5>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5 \+  && is_same<T6, typename decay<T6>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6 \+  && is_same<T7, typename decay<T7>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_8 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7 \+  && is_same<T8, typename decay<T8>::type>::value++#define ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF(n) \+  template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+  struct set_value_free_trait<T, void(ASIO_VARIADIC_TARGS(n))> : \+    conditional< \+      is_same<T, typename remove_reference<T>::type>::value \+        ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME(n), \+      typename conditional< \+        is_same<T, typename add_const<T>::type>::value, \+        no_set_value_free, \+        traits::set_value_free< \+          typename add_const<T>::type, \+          void(ASIO_VARIADIC_TARGS(n))> \+      >::type, \+      traits::set_value_free< \+        typename remove_reference<T>::type, \+        void(ASIO_VARIADIC_DECAY(n))> \+    >::type \+  { \+  }; \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF)+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_8++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // defined(ASIO_HAS_DEDUCED_SET_VALUE_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename Vs, typename>+struct set_value_free_default :+  detail::set_value_free_trait<T, Vs>+{+};++template <typename T, typename Vs, typename>+struct set_value_free :+  set_value_free_default<T, Vs>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_VALUE_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/set_value_member.hpp view
@@ -0,0 +1,234 @@+//+// traits/set_value_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SET_VALUE_MEMBER_HPP+#define ASIO_TRAITS_SET_VALUE_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"+#include "asio/detail/variadic_templates.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename Vs, typename = void>+struct set_value_member_default;++template <typename T, typename Vs, typename = void>+struct set_value_member;++} // namespace traits+namespace detail {++struct no_set_value_member+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <typename T, typename Vs, typename = void>+struct set_value_member_trait : no_set_value_member+{+};++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Vs>+struct set_value_member_trait<T, void(Vs...),+  typename void_type<+    decltype(declval<T>().set_value(declval<Vs>()...))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    declval<T>().set_value(declval<Vs>()...));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<T>().set_value(declval<Vs>()...)));+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct set_value_member_trait<T, void(),+  typename void_type<+    decltype(declval<T>().set_value())+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(declval<T>().set_value());++  ASIO_STATIC_CONSTEXPR(bool,+    is_noexcept = noexcept(declval<T>().set_value()));+};++#define ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF(n) \+  template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+  struct set_value_member_trait<T, void(ASIO_VARIADIC_TARGS(n)), \+    typename void_type< \+      decltype(declval<T>().set_value(ASIO_VARIADIC_DECLVAL(n))) \+    >::type> \+  { \+    ASIO_STATIC_CONSTEXPR(bool, is_valid = true); \+  \+    using result_type = decltype( \+      declval<T>().set_value(ASIO_VARIADIC_DECLVAL(n))); \+  \+    ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept( \+      declval<T>().set_value(ASIO_VARIADIC_DECLVAL(n)))); \+  }; \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF)+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#else // defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++template <typename T, typename Vs, typename = void>+struct set_value_member_trait;++#if defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T, typename... Vs>+struct set_value_member_trait<T, void(Vs...)> :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value+      && conjunction<is_same<Vs, typename decay<Vs>::type>...>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_set_value_member,+      traits::set_value_member<typename add_const<T>::type, void(Vs...)>+    >::type,+    traits::set_value_member<+      typename remove_reference<T>::type,+      void(typename decay<Vs>::type...)>+  >::type+{+};++#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename T>+struct set_value_member_trait<T, void()> :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_set_value_member,+      traits::set_value_member<typename add_const<T>::type, void()>+    >::type,+    traits::set_value_member<typename remove_reference<T>::type, void()>+  >::type+{+};++#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME(n) \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_##n++#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1 \+  && is_same<T1, typename decay<T1>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1 \+  && is_same<T2, typename decay<T2>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2 \+  && is_same<T3, typename decay<T3>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3 \+  && is_same<T4, typename decay<T4>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4 \+  && is_same<T5, typename decay<T5>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5 \+  && is_same<T6, typename decay<T6>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6 \+  && is_same<T7, typename decay<T7>::type>::value+#define ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_8 \+  ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7 \+  && is_same<T8, typename decay<T8>::type>::value++#define ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF(n) \+  template <typename T, ASIO_VARIADIC_TPARAMS(n)> \+  struct set_value_member_trait<T, void(ASIO_VARIADIC_TARGS(n))> : \+    conditional< \+      is_same<T, typename remove_reference<T>::type>::value \+        ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME(n), \+      typename conditional< \+        is_same<T, typename add_const<T>::type>::value, \+        no_set_value_member, \+        traits::set_value_member< \+          typename add_const<T>::type, \+          void(ASIO_VARIADIC_TARGS(n))> \+      >::type, \+      traits::set_value_member< \+        typename remove_reference<T>::type, \+        void(ASIO_VARIADIC_DECAY(n))> \+    >::type \+  { \+  }; \+  /**/+ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF)+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_TRAIT_DEF+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_1+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_2+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_3+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_4+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_5+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_6+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_7+#undef ASIO_PRIVATE_SET_VALUE_MEMBER_IS_SAME_8++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)++#endif // defined(ASIO_HAS_DEDUCED_SET_VALUE_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename Vs, typename>+struct set_value_member_default :+  detail::set_value_member_trait<T, Vs>+{+};++template <typename T, typename Vs, typename>+struct set_value_member :+  set_value_member_default<T, Vs>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SET_VALUE_MEMBER_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/start_free.hpp view
@@ -0,0 +1,108 @@+//+// traits/start_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_START_FREE_HPP+#define ASIO_TRAITS_START_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_START_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct start_free_default;++template <typename T, typename = void>+struct start_free;++} // namespace traits+namespace detail {++struct no_start_free+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT)++template <typename T, typename = void>+struct start_free_trait : no_start_free+{+};++template <typename T>+struct start_free_trait<T,+  typename void_type<+    decltype(start(declval<T>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(start(declval<T>()));++  ASIO_STATIC_CONSTEXPR(bool,+    is_noexcept = noexcept(start(declval<T>())));+};++#else // defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT)++template <typename T, typename = void>+struct start_free_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_start_free,+      traits::start_free<typename add_const<T>::type>+    >::type,+    traits::start_free<typename remove_reference<T>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_START_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct start_free_default :+  detail::start_free_trait<T>+{+};++template <typename T, typename>+struct start_free :+  start_free_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_START_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/start_member.hpp view
@@ -0,0 +1,108 @@+//+// traits/start_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_START_MEMBER_HPP+#define ASIO_TRAITS_START_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_START_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename T, typename = void>+struct start_member_default;++template <typename T, typename = void>+struct start_member;++} // namespace traits+namespace detail {++struct no_start_member+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++template <typename T, typename = void>+struct start_member_trait : no_start_member+{+};++template <typename T>+struct start_member_trait<T,+  typename void_type<+    decltype(declval<T>().start())+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(declval<T>().start());++  ASIO_STATIC_CONSTEXPR(bool,+    is_noexcept = noexcept(declval<T>().start()));+};++#else // defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++template <typename T, typename = void>+struct start_member_trait :+  conditional<+    is_same<T, typename remove_reference<T>::type>::value,+    typename conditional<+      is_same<T, typename add_const<T>::type>::value,+      no_start_member,+      traits::start_member<typename add_const<T>::type>+    >::type,+    traits::start_member<typename remove_reference<T>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_START_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename T, typename>+struct start_member_default :+  detail::start_member_trait<T>+{+};++template <typename T, typename>+struct start_member :+  start_member_default<T>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_START_MEMBER_HPP
link/modules/asio-standalone/asio/include/asio/traits/static_query.hpp view
@@ -2,7 +2,7 @@ // traits/static_query.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,10 +18,16 @@ #include "asio/detail/config.hpp" #include "asio/detail/type_traits.hpp" -#if defined(ASIO_HAS_VARIABLE_TEMPLATES) \+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_CONSTEXPR) \+  && defined(ASIO_HAS_VARIABLE_TEMPLATES) \   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE) # define ASIO_HAS_DEDUCED_STATIC_QUERY_TRAIT 1-#endif // defined(ASIO_HAS_VARIABLE_TEMPLATES)+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_CONSTEXPR)+       //   && defined(ASIO_HAS_VARIABLE_TEMPLATES)        //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  #include "asio/detail/push_options.hpp"@@ -40,20 +46,20 @@  struct no_static_query {-  static constexpr bool is_valid = false;-  static constexpr bool is_noexcept = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false); };  template <typename T, typename Property, typename = void> struct static_query_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_static_query,     traits::static_query<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; @@ -61,21 +67,21 @@  template <typename T, typename Property> struct static_query_trait<T, Property,-  void_t<-    decltype(decay_t<Property>::template static_query_v<T>)-  >>+  typename void_type<+    decltype(decay<Property>::type::template static_query_v<T>)+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);    using result_type = decltype(-      decay_t<Property>::template static_query_v<T>);+      decay<Property>::type::template static_query_v<T>); -  static constexpr bool is_noexcept =-    noexcept(decay_t<Property>::template static_query_v<T>);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept =+    noexcept(decay<Property>::type::template static_query_v<T>)); -  static constexpr result_type value() noexcept(is_noexcept)+  static ASIO_CONSTEXPR result_type value() noexcept(is_noexcept)   {-    return decay_t<Property>::template static_query_v<T>;+    return decay<Property>::type::template static_query_v<T>;   } }; 
link/modules/asio-standalone/asio/include/asio/traits/static_require.hpp view
@@ -2,7 +2,7 @@ // traits/static_require.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,7 +19,11 @@ #include "asio/detail/type_traits.hpp" #include "asio/traits/static_query.hpp" -#define ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT 1+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT)+# define ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)  #include "asio/detail/push_options.hpp" @@ -37,31 +41,33 @@  struct no_static_require {-  static constexpr bool is_valid = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false); };  template <typename T, typename Property, typename = void> struct static_require_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_static_require,     traits::static_require<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; +#if defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)+ #if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  template <typename T, typename Property> struct static_require_trait<T, Property,-  enable_if_t<-    decay_t<Property>::value() == traits::static_query<T, Property>::value()-  >>+  typename enable_if<+    decay<Property>::type::value() == traits::static_query<T, Property>::value()+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true); };  #else // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)@@ -70,29 +76,31 @@  template <typename T, typename Property> true_type static_require_test(T*, Property*,-    enable_if_t<+    typename enable_if<       Property::value() == traits::static_query<T, Property>::value()-    >* = 0);+    >::type* = 0);  template <typename T, typename Property> struct has_static_require {-  static constexpr bool value =+  ASIO_STATIC_CONSTEXPR(bool, value =     decltype((static_require_test)(-      static_cast<T*>(0), static_cast<Property*>(0)))::value;+      static_cast<T*>(0), static_cast<Property*>(0)))::value); };  template <typename T, typename Property> struct static_require_trait<T, Property,-  enable_if_t<-    has_static_require<decay_t<T>,-      decay_t<Property>>::value-  >>+  typename enable_if<+    has_static_require<typename decay<T>::type,+      typename decay<Property>::type>::value+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true); };  #endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#endif // defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_TRAIT)  } // namespace detail namespace traits {
link/modules/asio-standalone/asio/include/asio/traits/static_require_concept.hpp view
@@ -2,7 +2,7 @@ // traits/static_require_concept.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -19,7 +19,11 @@ #include "asio/detail/type_traits.hpp" #include "asio/traits/static_query.hpp" -#define ASIO_HAS_DEDUCED_STATIC_REQUIRE_CONCEPT_TRAIT 1+#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT)+# define ASIO_HAS_DEDUCED_STATIC_REQUIRE_CONCEPT_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)  #include "asio/detail/push_options.hpp" @@ -37,31 +41,33 @@  struct no_static_require_concept {-  static constexpr bool is_valid = false;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false); };  template <typename T, typename Property, typename = void> struct static_require_concept_trait :-  conditional_t<-    is_same<T, decay_t<T>>::value-      && is_same<Property, decay_t<Property>>::value,+  conditional<+    is_same<T, typename decay<T>::type>::value+      && is_same<Property, typename decay<Property>::type>::value,     no_static_require_concept,     traits::static_require_concept<-      decay_t<T>,-      decay_t<Property>>-  >+      typename decay<T>::type,+      typename decay<Property>::type>+  >::type { }; +#if defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_CONCEPT_TRAIT)+ #if defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)  template <typename T, typename Property> struct static_require_concept_trait<T, Property,-  enable_if_t<-    decay_t<Property>::value() == traits::static_query<T, Property>::value()-  >>+  typename enable_if<+    decay<Property>::type::value() == traits::static_query<T, Property>::value()+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true); };  #else // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)@@ -70,29 +76,31 @@  template <typename T, typename Property> true_type static_require_concept_test(T*, Property*,-    enable_if_t<+    typename enable_if<       Property::value() == traits::static_query<T, Property>::value()-    >* = 0);+    >::type* = 0);  template <typename T, typename Property> struct has_static_require_concept {-  static constexpr bool value =+  ASIO_STATIC_CONSTEXPR(bool, value =     decltype((static_require_concept_test)(-      static_cast<T*>(0), static_cast<Property*>(0)))::value;+      static_cast<T*>(0), static_cast<Property*>(0)))::value); };  template <typename T, typename Property> struct static_require_concept_trait<T, Property,-  enable_if_t<-    has_static_require_concept<decay_t<T>,-      decay_t<Property>>::value-  >>+  typename enable_if<+    has_static_require_concept<typename decay<T>::type,+      typename decay<Property>::type>::value+  >::type> {-  static constexpr bool is_valid = true;+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true); };  #endif // defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#endif // defined(ASIO_HAS_DEDUCED_STATIC_REQUIRE_CONCEPT_TRAIT)  } // namespace detail namespace traits {
+ link/modules/asio-standalone/asio/include/asio/traits/submit_free.hpp view
@@ -0,0 +1,112 @@+//+// traits/submit_free.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SUBMIT_FREE_HPP+#define ASIO_TRAITS_SUBMIT_FREE_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename S, typename R, typename = void>+struct submit_free_default;++template <typename S, typename R, typename = void>+struct submit_free;++} // namespace traits+namespace detail {++struct no_submit_free+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)++template <typename S, typename R, typename = void>+struct submit_free_trait : no_submit_free+{+};++template <typename S, typename R>+struct submit_free_trait<S, R,+  typename void_type<+    decltype(submit(declval<S>(), declval<R>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    submit(declval<S>(), declval<R>()));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    submit(declval<S>(), declval<R>())));+};++#else // defined(ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)++template <typename S, typename R, typename = void>+struct submit_free_trait :+  conditional<+    is_same<S, typename remove_reference<S>::type>::value+      && is_same<R, typename decay<R>::type>::value,+    typename conditional<+      is_same<S, typename add_const<S>::type>::value,+      no_submit_free,+      traits::submit_free<typename add_const<S>::type, R>+    >::type,+    traits::submit_free<+      typename remove_reference<S>::type,+      typename decay<R>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SUBMIT_FREE_TRAIT)++} // namespace detail+namespace traits {++template <typename S, typename R, typename>+struct submit_free_default :+  detail::submit_free_trait<S, R>+{+};++template <typename S, typename R, typename>+struct submit_free :+  submit_free_default<S, R>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SUBMIT_FREE_HPP
+ link/modules/asio-standalone/asio/include/asio/traits/submit_member.hpp view
@@ -0,0 +1,112 @@+//+// traits/submit_member.hpp+// ~~~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ASIO_TRAITS_SUBMIT_MEMBER_HPP+#define ASIO_TRAITS_SUBMIT_MEMBER_HPP++#if defined(_MSC_VER) && (_MSC_VER >= 1200)+# pragma once+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)++#include "asio/detail/config.hpp"+#include "asio/detail/type_traits.hpp"++#if defined(ASIO_HAS_DECLTYPE) \+  && defined(ASIO_HAS_NOEXCEPT) \+  && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)+# define ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT 1+#endif // defined(ASIO_HAS_DECLTYPE)+       //   && defined(ASIO_HAS_NOEXCEPT)+       //   && defined(ASIO_HAS_WORKING_EXPRESSION_SFINAE)++#include "asio/detail/push_options.hpp"++namespace asio {+namespace traits {++template <typename S, typename R, typename = void>+struct submit_member_default;++template <typename S, typename R, typename = void>+struct submit_member;++} // namespace traits+namespace detail {++struct no_submit_member+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = false);+  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);+};++#if defined(ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)++template <typename S, typename R, typename = void>+struct submit_member_trait : no_submit_member+{+};++template <typename S, typename R>+struct submit_member_trait<S, R,+  typename void_type<+    decltype(declval<S>().submit(declval<R>()))+  >::type>+{+  ASIO_STATIC_CONSTEXPR(bool, is_valid = true);++  using result_type = decltype(+    declval<S>().submit(declval<R>()));++  ASIO_STATIC_CONSTEXPR(bool, is_noexcept = noexcept(+    declval<S>().submit(declval<R>())));+};++#else // defined(ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)++template <typename S, typename R, typename = void>+struct submit_member_trait :+  conditional<+    is_same<S, typename remove_reference<S>::type>::value+      && is_same<R, typename decay<R>::type>::value,+    typename conditional<+      is_same<S, typename add_const<S>::type>::value,+      no_submit_member,+      traits::submit_member<typename add_const<S>::type, R>+    >::type,+    traits::submit_member<+      typename remove_reference<S>::type,+      typename decay<R>::type>+  >::type+{+};++#endif // defined(ASIO_HAS_DEDUCED_SUBMIT_MEMBER_TRAIT)++} // namespace detail+namespace traits {++template <typename S, typename R, typename>+struct submit_member_default :+  detail::submit_member_trait<S, R>+{+};++template <typename S, typename R, typename>+struct submit_member :+  submit_member_default<S, R>+{+};++} // namespace traits+} // namespace asio++#include "asio/detail/pop_options.hpp"++#endif // ASIO_TRAITS_SUBMIT_MEMBER_HPP
link/modules/asio-standalone/asio/include/asio/ts/buffer.hpp view
@@ -2,7 +2,7 @@ // ts/buffer.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ts/executor.hpp view
@@ -2,7 +2,7 @@ // ts/executor.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ts/internet.hpp view
@@ -2,7 +2,7 @@ // ts/internet.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ts/io_context.hpp view
@@ -2,7 +2,7 @@ // ts/io_context.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ts/net.hpp view
@@ -2,7 +2,7 @@ // ts/net.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ts/netfwd.hpp view
@@ -2,7 +2,7 @@ // ts/netfwd.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -16,8 +16,15 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)  #include "asio/detail/config.hpp"-#include "asio/detail/chrono.hpp" +#if defined(ASIO_HAS_CHRONO)+# include "asio/detail/chrono.hpp"+#endif // defined(ASIO_HAS_CHRONO)++#if defined(ASIO_HAS_BOOST_DATE_TIME)+# include "asio/detail/date_time_fwd.hpp"+#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ #if !defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) #include "asio/execution/blocking.hpp" #include "asio/execution/outstanding_work.hpp"@@ -59,9 +66,20 @@ #if !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL) #define ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL +#if defined(ASIO_HAS_VARIADIC_TEMPLATES)+ template <typename... SupportableProperties> class any_executor; +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)++template <typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void,+    typename = void, typename = void, typename = void>+class any_executor;++#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)+ #endif // !defined(ASIO_EXECUTION_ANY_EXECUTOR_FWD_DECL)  template <typename U>@@ -84,6 +102,13 @@ template <typename Clock> struct wait_traits; +#if defined(ASIO_HAS_BOOST_DATE_TIME)++template <typename Time>+struct time_traits;++#endif // defined(ASIO_HAS_BOOST_DATE_TIME)+ #if !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) #define ASIO_BASIC_WAITABLE_TIMER_FWD_DECL @@ -94,6 +119,8 @@  #endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) +#if defined(ASIO_HAS_CHRONO)+ typedef basic_waitable_timer<chrono::system_clock> system_timer;  typedef basic_waitable_timer<chrono::steady_clock> steady_timer;@@ -101,6 +128,8 @@ typedef basic_waitable_timer<chrono::high_resolution_clock>   high_resolution_timer; +#endif // defined(ASIO_HAS_CHRONO)+ #if !defined(ASIO_BASIC_SOCKET_FWD_DECL) #define ASIO_BASIC_SOCKET_FWD_DECL @@ -139,8 +168,14 @@  // Forward declaration with defaulted arguments. template <typename Protocol,+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+  || defined(GENERATING_DOCUMENTATION)+    typename Clock = boost::posix_time::ptime,+    typename WaitTraits = time_traits<Clock> >+#else     typename Clock = chrono::steady_clock,-    typename WaitTraits = wait_traits<Clock>>+    typename WaitTraits = wait_traits<Clock> >+#endif class basic_socket_streambuf;  #endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)@@ -150,8 +185,14 @@  // Forward declaration with defaulted arguments. template <typename Protocol,+#if defined(ASIO_HAS_BOOST_DATE_TIME) \+  || defined(GENERATING_DOCUMENTATION)+    typename Clock = boost::posix_time::ptime,+    typename WaitTraits = time_traits<Clock> >+#else     typename Clock = chrono::steady_clock,-    typename WaitTraits = wait_traits<Clock>>+    typename WaitTraits = wait_traits<Clock> >+#endif class basic_socket_iostream;  #endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
link/modules/asio-standalone/asio/include/asio/ts/socket.hpp view
@@ -2,7 +2,7 @@ // ts/socket.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/ts/timer.hpp view
@@ -2,7 +2,7 @@ // ts/timer.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/unyield.hpp view
@@ -2,7 +2,7 @@ // unyield.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/use_awaitable.hpp view
@@ -2,7 +2,7 @@ // use_awaitable.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -53,7 +53,7 @@ struct use_awaitable_t {   /// Default constructor.-  constexpr use_awaitable_t(+  ASIO_CONSTEXPR use_awaitable_t( #if defined(ASIO_ENABLE_HANDLER_TRACKING) # if defined(ASIO_HAS_SOURCE_LOCATION)       detail::source_location location = detail::source_location::current()@@ -75,7 +75,7 @@   }    /// Constructor used to specify file name, line, and function name.-  constexpr use_awaitable_t(const char* file_name,+  ASIO_CONSTEXPR use_awaitable_t(const char* file_name,       int line, const char* function_name) #if defined(ASIO_ENABLE_HANDLER_TRACKING)     : file_name_(file_name),@@ -101,13 +101,13 @@     /// Construct the adapted executor from the inner executor type.     template <typename InnerExecutor1>     executor_with_default(const InnerExecutor1& ex,-        constraint_t<-          conditional_t<+        typename constraint<+          conditional<             !is_same<InnerExecutor1, executor_with_default>::value,             is_convertible<InnerExecutor1, InnerExecutor>,             false_type-          >::value-        > = 0) noexcept+          >::type::value+        >::type = 0) ASIO_NOEXCEPT       : InnerExecutor(ex)     {     }@@ -115,21 +115,25 @@    /// Type alias to adapt an I/O object to use @c use_awaitable_t as its   /// default completion token type.+#if defined(ASIO_HAS_ALIAS_TEMPLATES) \+  || defined(GENERATING_DOCUMENTATION)   template <typename T>   using as_default_on_t = typename T::template rebind_executor<-      executor_with_default<typename T::executor_type>>::other;+      executor_with_default<typename T::executor_type> >::other;+#endif // defined(ASIO_HAS_ALIAS_TEMPLATES)+       //   || defined(GENERATING_DOCUMENTATION)    /// Function helper to adapt an I/O object to use @c use_awaitable_t as its   /// default completion token type.   template <typename T>-  static typename decay_t<T>::template rebind_executor<-      executor_with_default<typename decay_t<T>::executor_type>+  static typename decay<T>::type::template rebind_executor<+      executor_with_default<typename decay<T>::type::executor_type>     >::other-  as_default_on(T&& object)+  as_default_on(ASIO_MOVE_ARG(T) object)   {-    return typename decay_t<T>::template rebind_executor<-        executor_with_default<typename decay_t<T>::executor_type>-      >::other(static_cast<T&&>(object));+    return typename decay<T>::type::template rebind_executor<+        executor_with_default<typename decay<T>::type::executor_type>+      >::other(ASIO_MOVE_CAST(T)(object));   }  #if defined(ASIO_ENABLE_HANDLER_TRACKING)@@ -145,9 +149,11 @@  * See the documentation for asio::use_awaitable_t for a usage example.  */ #if defined(GENERATING_DOCUMENTATION)-ASIO_INLINE_VARIABLE constexpr use_awaitable_t<> use_awaitable;-#else-ASIO_INLINE_VARIABLE constexpr use_awaitable_t<> use_awaitable(0, 0, 0);+constexpr use_awaitable_t<> use_awaitable;+#elif defined(ASIO_HAS_CONSTEXPR)+constexpr use_awaitable_t<> use_awaitable(0, 0, 0);+#elif defined(ASIO_MSVC)+__declspec(selectany) use_awaitable_t<> use_awaitable(0, 0, 0); #endif  } // namespace asio
link/modules/asio-standalone/asio/include/asio/use_future.hpp view
@@ -2,7 +2,7 @@ // use_future.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -54,7 +54,7 @@  * completes with an error_code indicating failure, it is converted into a  * system_error and passed back to the caller via the future.  */-template <typename Allocator = std::allocator<void>>+template <typename Allocator = std::allocator<void> > class use_future_t { public:@@ -63,7 +63,7 @@   typedef Allocator allocator_type;    /// Construct using default-constructed allocator.-  constexpr use_future_t()+  ASIO_CONSTEXPR use_future_t()   {   } @@ -73,6 +73,15 @@   {   } +#if !defined(ASIO_NO_DEPRECATED)+  /// (Deprecated: Use rebind().) Specify an alternate allocator.+  template <typename OtherAllocator>+  use_future_t<OtherAllocator> operator[](const OtherAllocator& allocator) const+  {+    return use_future_t<OtherAllocator>(allocator);+  }+#endif // !defined(ASIO_NO_DEPRECATED)+   /// Specify an alternate allocator.   template <typename OtherAllocator>   use_future_t<OtherAllocator> rebind(const OtherAllocator& allocator) const@@ -90,7 +99,7 @@   /**    * The @c package function is used to adapt a function object as a packaged    * task. When this adapter is passed as a completion token to an asynchronous-   * operation, the result of the function object is returned via a std::future.+   * operation, the result of the function object is retuned via a std::future.    *    * @par Example    *@@ -107,16 +116,16 @@ #if defined(GENERATING_DOCUMENTATION)   unspecified #else // defined(GENERATING_DOCUMENTATION)-  detail::packaged_token<decay_t<Function>, Allocator>+  detail::packaged_token<typename decay<Function>::type, Allocator> #endif // defined(GENERATING_DOCUMENTATION)-  operator()(Function&& f) const;+  operator()(ASIO_MOVE_ARG(Function) f) const;  private:   // Helper type to ensure that use_future can be constexpr default-constructed   // even when std::allocator<void> can't be.   struct std_allocator_void   {-    constexpr std_allocator_void()+    ASIO_CONSTEXPR std_allocator_void()     {     } @@ -126,9 +135,9 @@     }   }; -  conditional_t<+  typename conditional<     is_same<std::allocator<void>, Allocator>::value,-    std_allocator_void, Allocator> allocator_;+    std_allocator_void, Allocator>::type allocator_; };  /// A @ref completion_token object that causes an asynchronous operation to@@ -136,7 +145,11 @@ /**  * See the documentation for asio::use_future_t for a usage example.  */-ASIO_INLINE_VARIABLE constexpr use_future_t<> use_future;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr use_future_t<> use_future;+#elif defined(ASIO_MSVC)+__declspec(selectany) use_future_t<> use_future;+#endif  } // namespace asio 
link/modules/asio-standalone/asio/include/asio/uses_executor.hpp view
@@ -2,7 +2,7 @@ // uses_executor.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -34,7 +34,7 @@ struct executor_arg_t {   /// Constructor.-  constexpr executor_arg_t() noexcept+  ASIO_CONSTEXPR executor_arg_t() ASIO_NOEXCEPT   {   } };@@ -45,7 +45,11 @@  * See asio::executor_arg_t and asio::uses_executor  * for more information.  */-ASIO_INLINE_VARIABLE constexpr executor_arg_t executor_arg;+#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)+constexpr executor_arg_t executor_arg;+#elif defined(ASIO_MSVC)+__declspec(selectany) executor_arg_t executor_arg;+#endif  /// The uses_executor trait detects whether a type T has an associated executor /// that is convertible from type Executor.
link/modules/asio-standalone/asio/include/asio/version.hpp view
@@ -2,7 +2,7 @@ // version.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -18,6 +18,6 @@ // ASIO_VERSION % 100 is the sub-minor version // ASIO_VERSION / 100 % 1000 is the minor version // ASIO_VERSION / 100000 is the major version-#define ASIO_VERSION 103600 // 1.36.0+#define ASIO_VERSION 102800 // 1.28.0  #endif // ASIO_VERSION_HPP
link/modules/asio-standalone/asio/include/asio/wait_traits.hpp view
@@ -2,7 +2,7 @@ // wait_traits.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/windows/basic_object_handle.hpp view
@@ -2,7 +2,7 @@ // windows/basic_object_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying@@ -21,7 +21,6 @@ #if defined(ASIO_HAS_WINDOWS_OBJECT_HANDLE) \   || defined(GENERATING_DOCUMENTATION) -#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/io_object_impl.hpp"@@ -30,6 +29,10 @@ #include "asio/error.hpp" #include "asio/execution_context.hpp" +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -96,10 +99,10 @@    */   template <typename ExecutionContext>   explicit basic_object_handle(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {   }@@ -142,9 +145,9 @@   template <typename ExecutionContext>   basic_object_handle(ExecutionContext& context,       const native_handle_type& native_handle,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -152,6 +155,7 @@     asio::detail::throw_error(ec, "assign");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct an object handle from another.   /**    * This constructor moves an object handle from one object to another.@@ -202,10 +206,10 @@    */   template<typename Executor1>   basic_object_handle(basic_object_handle<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(std::move(other.impl_))   {   }@@ -222,17 +226,18 @@    * constructor.    */   template<typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_object_handle&-  > operator=(basic_object_handle<Executor1>&& other)+  >::type operator=(basic_object_handle<Executor1>&& other)   {     impl_ = std::move(other.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -415,19 +420,22 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code) @endcode    */   template <       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code))-        WaitToken = default_completion_token_t<executor_type>>-  auto async_wait(-      WaitToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        WaitToken ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WaitToken,+      void (asio::error_code))+  async_wait(+      ASIO_MOVE_ARG(WaitToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WaitToken, void (asio::error_code)>(-        declval<initiate_async_wait>(), token))+          declval<initiate_async_wait>(), token)))   {     return async_initiate<WaitToken, void (asio::error_code)>(         initiate_async_wait(this), token);@@ -435,8 +443,8 @@  private:   // Disallow copying and assignment.-  basic_object_handle(const basic_object_handle&) = delete;-  basic_object_handle& operator=(const basic_object_handle&) = delete;+  basic_object_handle(const basic_object_handle&) ASIO_DELETED;+  basic_object_handle& operator=(const basic_object_handle&) ASIO_DELETED;    class initiate_async_wait   {@@ -448,13 +456,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WaitHandler>-    void operator()(WaitHandler&& handler) const+    void operator()(ASIO_MOVE_ARG(WaitHandler) handler) const     {       // If you get an error on the following line it means that your handler       // does not meet the documented type requirements for a WaitHandler.
link/modules/asio-standalone/asio/include/asio/windows/basic_overlapped_handle.hpp view
@@ -2,7 +2,7 @@ // windows/basic_overlapped_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -22,7 +22,6 @@   || defined(GENERATING_DOCUMENTATION)  #include <cstddef>-#include <utility> #include "asio/any_io_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/io_object_impl.hpp"@@ -31,6 +30,10 @@ #include "asio/error.hpp" #include "asio/execution_context.hpp" +#if defined(ASIO_HAS_MOVE)+# include <utility>+#endif // defined(ASIO_HAS_MOVE)+ #include "asio/detail/push_options.hpp"  namespace asio {@@ -96,10 +99,10 @@    */   template <typename ExecutionContext>   explicit basic_overlapped_handle(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(0, 0, context)   {   }@@ -142,9 +145,9 @@   template <typename ExecutionContext>   basic_overlapped_handle(ExecutionContext& context,       const native_handle_type& native_handle,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : impl_(0, 0, context)   {     asio::error_code ec;@@ -152,6 +155,7 @@     asio::detail::throw_error(ec, "assign");   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct an overlapped handle from another.   /**    * This constructor moves a handle from one object to another.@@ -203,10 +207,10 @@    */   template<typename Executor1>   basic_overlapped_handle(basic_overlapped_handle<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : impl_(std::move(other.impl_))   {   }@@ -223,17 +227,18 @@    * constructor.    */   template<typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_overlapped_handle&-  > operator=(basic_overlapped_handle<Executor1>&& other)+  >::type operator=(basic_overlapped_handle<Executor1>&& other)   {     impl_ = std::move(other.impl_);     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Get the executor associated with the object.-  const executor_type& get_executor() noexcept+  const executor_type& get_executor() ASIO_NOEXCEPT   {     return impl_.get_executor();   }@@ -438,9 +443,9 @@  private:   // Disallow copying and assignment.-  basic_overlapped_handle(const basic_overlapped_handle&) = delete;+  basic_overlapped_handle(const basic_overlapped_handle&) ASIO_DELETED;   basic_overlapped_handle& operator=(-      const basic_overlapped_handle&) = delete;+      const basic_overlapped_handle&) ASIO_DELETED; };  } // namespace windows
link/modules/asio-standalone/asio/include/asio/windows/basic_random_access_handle.hpp view
@@ -2,7 +2,7 @@ // windows/basic_random_access_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -88,10 +88,10 @@    */   template <typename ExecutionContext>   explicit basic_random_access_handle(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_overlapped_handle<Executor>(context)   {   }@@ -131,13 +131,14 @@   template <typename ExecutionContext>   basic_random_access_handle(ExecutionContext& context,       const native_handle_type& handle,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_overlapped_handle<Executor>(context, handle)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a random-access handle from another.   /**    * This constructor moves a random-access handle from one object to another.@@ -186,10 +187,10 @@    */   template<typename Executor1>   basic_random_access_handle(basic_random_access_handle<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_overlapped_handle<Executor>(std::move(other))   {   }@@ -208,14 +209,15 @@    * constructor.    */   template<typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_random_access_handle&-  > operator=(basic_random_access_handle<Executor1>&& other)+  >::type operator=(basic_random_access_handle<Executor1>&& other)   {     basic_overlapped_handle<Executor>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Write some data to the handle at the specified offset.   /**@@ -308,7 +310,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -338,13 +340,18 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_write_some_at(uint64_t offset, const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_write_some_at(uint64_t offset,+      const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_write_some_at>(), token, offset, buffers))+          declval<initiate_async_write_some_at>(), token, offset, buffers)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -444,7 +451,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -475,13 +482,18 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_read_some_at(uint64_t offset, const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_read_some_at(uint64_t offset,+      const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_read_some_at>(), token, offset, buffers))+          declval<initiate_async_read_some_at>(), token, offset, buffers)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -499,13 +511,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         uint64_t offset, const ConstBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler@@ -532,13 +544,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         uint64_t offset, const MutableBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/windows/basic_stream_handle.hpp view
@@ -2,7 +2,7 @@ // windows/basic_stream_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -91,10 +91,10 @@    */   template <typename ExecutionContext>   explicit basic_stream_handle(ExecutionContext& context,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_overlapped_handle<Executor>(context)   {   }@@ -133,13 +133,14 @@   template <typename ExecutionContext>   basic_stream_handle(ExecutionContext& context,       const native_handle_type& handle,-      constraint_t<+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)     : basic_overlapped_handle<Executor>(context, handle)   {   } +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)   /// Move-construct a stream handle from another.   /**    * This constructor moves a stream handle from one object to another.@@ -186,10 +187,10 @@    */   template<typename Executor1>   basic_stream_handle(basic_stream_handle<Executor1>&& other,-      constraint_t<+      typename constraint<         is_convertible<Executor1, Executor>::value,         defaulted_constraint-      > = defaulted_constraint())+      >::type = defaulted_constraint())     : basic_overlapped_handle<Executor>(std::move(other))   {   }@@ -206,14 +207,15 @@    * constructor.    */   template<typename Executor1>-  constraint_t<+  typename constraint<     is_convertible<Executor1, Executor>::value,     basic_stream_handle&-  > operator=(basic_stream_handle<Executor1>&& other)+  >::type operator=(basic_stream_handle<Executor1>&& other)   {     basic_overlapped_handle<Executor>::operator=(std::move(other));     return *this;   }+#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)    /// Write some data to the handle.   /**@@ -299,7 +301,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -329,13 +331,17 @@    */   template <typename ConstBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) WriteToken = default_completion_token_t<executor_type>>-  auto async_write_some(const ConstBufferSequence& buffers,-      WriteToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) WriteToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+      void (asio::error_code, std::size_t))+  async_write_some(const ConstBufferSequence& buffers,+      ASIO_MOVE_ARG(WriteToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<WriteToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_write_some>(), token, buffers))+          declval<initiate_async_write_some>(), token, buffers)))   {     return async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(@@ -428,7 +434,7 @@    * Regardless of whether the asynchronous operation completes immediately or    * not, the completion handler will not be invoked from within this function.    * On immediate completion, invocation of the handler will be performed in a-   * manner equivalent to using asio::async_immediate().+   * manner equivalent to using asio::post().    *    * @par Completion Signature    * @code void(asio::error_code, std::size_t) @endcode@@ -459,13 +465,17 @@    */   template <typename MutableBufferSequence,       ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-        std::size_t)) ReadToken = default_completion_token_t<executor_type>>-  auto async_read_some(const MutableBufferSequence& buffers,-      ReadToken&& token = default_completion_token_t<executor_type>())-    -> decltype(+        std::size_t)) ReadToken+          ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>+  ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(ReadToken,+      void (asio::error_code, std::size_t))+  async_read_some(const MutableBufferSequence& buffers,+      ASIO_MOVE_ARG(ReadToken) token+        ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))+    ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((       async_initiate<ReadToken,         void (asio::error_code, std::size_t)>(-          declval<initiate_async_read_some>(), token, buffers))+          declval<initiate_async_read_some>(), token, buffers)))   {     return async_initiate<ReadToken,       void (asio::error_code, std::size_t)>(@@ -483,13 +493,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename WriteHandler, typename ConstBufferSequence>-    void operator()(WriteHandler&& handler,+    void operator()(ASIO_MOVE_ARG(WriteHandler) handler,         const ConstBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler@@ -516,13 +526,13 @@     {     } -    const executor_type& get_executor() const noexcept+    const executor_type& get_executor() const ASIO_NOEXCEPT     {       return self_->get_executor();     }      template <typename ReadHandler, typename MutableBufferSequence>-    void operator()(ReadHandler&& handler,+    void operator()(ASIO_MOVE_ARG(ReadHandler) handler,         const MutableBufferSequence& buffers) const     {       // If you get an error on the following line it means that your handler
link/modules/asio-standalone/asio/include/asio/windows/object_handle.hpp view
@@ -2,7 +2,7 @@ // windows/object_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2011 Boris Schaeling (boris@highscore.de) // // Distributed under the Boost Software License, Version 1.0. (See accompanying
link/modules/asio-standalone/asio/include/asio/windows/overlapped_handle.hpp view
@@ -2,7 +2,7 @@ // windows/overlapped_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/windows/overlapped_ptr.hpp view
@@ -2,7 +2,7 @@ // windows/overlapped_ptr.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -51,23 +51,23 @@   /// Construct an overlapped_ptr to contain the specified handler.   template <typename ExecutionContext, typename Handler>   explicit overlapped_ptr(ExecutionContext& context,-      Handler&& handler,-      constraint_t<+      ASIO_MOVE_ARG(Handler) handler,+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)-    : impl_(context.get_executor(), static_cast<Handler&&>(handler))+      >::type = 0)+    : impl_(context.get_executor(), ASIO_MOVE_CAST(Handler)(handler))   {   }    /// Construct an overlapped_ptr to contain the specified handler.   template <typename Executor, typename Handler>   explicit overlapped_ptr(const Executor& ex,-      Handler&& handler,-      constraint_t<+      ASIO_MOVE_ARG(Handler) handler,+      typename constraint<         execution::is_executor<Executor>::value           || is_executor<Executor>::value-      > = 0)-    : impl_(ex, static_cast<Handler&&>(handler))+      >::type = 0)+    : impl_(ex, ASIO_MOVE_CAST(Handler)(handler))   {   } @@ -85,24 +85,24 @@   /// Reset to contain the specified handler, freeing any current OVERLAPPED   /// object.   template <typename ExecutionContext, typename Handler>-  void reset(ExecutionContext& context, Handler&& handler,-      constraint_t<+  void reset(ExecutionContext& context, ASIO_MOVE_ARG(Handler) handler,+      typename constraint<         is_convertible<ExecutionContext&, execution_context&>::value-      > = 0)+      >::type = 0)   {-    impl_.reset(context.get_executor(), static_cast<Handler&&>(handler));+    impl_.reset(context.get_executor(), ASIO_MOVE_CAST(Handler)(handler));   }    /// Reset to contain the specified handler, freeing any current OVERLAPPED   /// object.   template <typename Executor, typename Handler>-  void reset(const Executor& ex, Handler&& handler,-      constraint_t<+  void reset(const Executor& ex, ASIO_MOVE_ARG(Handler) handler,+      typename constraint<         execution::is_executor<Executor>::value           || is_executor<Executor>::value-      > = 0)+      >::type = 0)   {-    impl_.reset(ex, static_cast<Handler&&>(handler));+    impl_.reset(ex, ASIO_MOVE_CAST(Handler)(handler));   }    /// Get the contained OVERLAPPED object.
link/modules/asio-standalone/asio/include/asio/windows/random_access_handle.hpp view
@@ -2,7 +2,7 @@ // windows/random_access_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/windows/stream_handle.hpp view
@@ -2,7 +2,7 @@ // windows/stream_handle.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/writable_pipe.hpp view
@@ -2,7 +2,7 @@ // writable_pipe.hpp // ~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/include/asio/write.hpp view
@@ -2,7 +2,7 @@ // write.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -85,9 +85,9 @@  */ template <typename SyncWriteStream, typename ConstBufferSequence> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,-    constraint_t<+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    > = 0);+    >::type = 0);  /// Write all of the supplied data to a stream before returning. /**@@ -128,9 +128,9 @@ template <typename SyncWriteStream, typename ConstBufferSequence> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,     asio::error_code& ec,-    constraint_t<+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    > = 0);+    >::type = 0);  /// Write a certain amount of data to a stream before returning. /**@@ -182,12 +182,9 @@     typename CompletionCondition> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,     CompletionCondition completion_condition,-    constraint_t<+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    >::type = 0);  /// Write a certain amount of data to a stream before returning. /**@@ -232,12 +229,9 @@     typename CompletionCondition> std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    >::type = 0);  #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -270,13 +264,13 @@  */ template <typename SyncWriteStream, typename DynamicBuffer_v1> std::size_t write(SyncWriteStream& s,-    DynamicBuffer_v1&& buffers,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Write all of the supplied data to a stream before returning. /**@@ -307,14 +301,14 @@  */ template <typename SyncWriteStream, typename DynamicBuffer_v1> std::size_t write(SyncWriteStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0);+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Write a certain amount of data to a stream before returning. /**@@ -355,17 +349,14 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1,     typename CompletionCondition> std::size_t write(SyncWriteStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  /// Write a certain amount of data to a stream before returning. /**@@ -407,17 +398,14 @@ template <typename SyncWriteStream, typename DynamicBuffer_v1,     typename CompletionCondition> std::size_t write(SyncWriteStream& s,-    DynamicBuffer_v1&& buffers,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0);  #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -519,10 +507,7 @@ template <typename SyncWriteStream, typename Allocator,     typename CompletionCondition> std::size_t write(SyncWriteStream& s, basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition);  /// Write a certain amount of data to a stream before returning. /**@@ -563,10 +548,7 @@ template <typename SyncWriteStream, typename Allocator,     typename CompletionCondition> std::size_t write(SyncWriteStream& s, basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition, asio::error_code& ec);  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -601,9 +583,9 @@  */ template <typename SyncWriteStream, typename DynamicBuffer_v2> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  /// Write all of the supplied data to a stream before returning. /**@@ -635,9 +617,9 @@ template <typename SyncWriteStream, typename DynamicBuffer_v2> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,     asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0);+    >::type = 0);  /// Write a certain amount of data to a stream before returning. /**@@ -679,12 +661,9 @@     typename CompletionCondition> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    >::type = 0);  /// Write a certain amount of data to a stream before returning. /**@@ -727,12 +706,9 @@     typename CompletionCondition> std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    >::type = 0);  /*@}*/ /**@@ -786,7 +762,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -814,27 +790,22 @@ template <typename AsyncWriteStream, typename ConstBufferSequence,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       std::size_t)) WriteToken-        = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,-    WriteToken&& token-      = default_completion_token_t<typename AsyncWriteStream::executor_type>(),-    constraint_t<+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncWriteStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,+    ASIO_MOVE_ARG(WriteToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncWriteStream::executor_type),+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    > = 0,-    constraint_t<-      !is_completion_condition<decay_t<WriteToken>>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_write<AsyncWriteStream>>(),-        token, buffers, transfer_all()))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write<AsyncWriteStream>(s),-      token, buffers, transfer_all());-}+        declval<detail::initiate_async_write<AsyncWriteStream> >(),+        token, buffers, transfer_all())));  /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -893,7 +864,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -922,31 +893,21 @@ template <typename AsyncWriteStream,     typename ConstBufferSequence, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) WriteToken-        = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,+      std::size_t)) WriteToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,     CompletionCondition completion_condition,-    WriteToken&& token-      = default_completion_token_t<typename AsyncWriteStream::executor_type>(),-    constraint_t<+    ASIO_MOVE_ARG(WriteToken) token,+    typename constraint<       is_const_buffer_sequence<ConstBufferSequence>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_write<AsyncWriteStream>>(),+        declval<detail::initiate_async_write<AsyncWriteStream> >(),         token, buffers,-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write<AsyncWriteStream>(s),-      token, buffers,-      static_cast<CompletionCondition&&>(completion_condition));-}+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  #if !defined(ASIO_NO_DYNAMIC_BUFFER_V1) @@ -993,7 +954,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1012,32 +973,27 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v1,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       std::size_t)) WriteToken-        = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v1&& buffers,-    WriteToken&& token-      = default_completion_token_t<typename AsyncWriteStream::executor_type>(),-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_completion_condition<decay_t<WriteToken>>::value-    > = 0)-  -> decltype(+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncWriteStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,+    ASIO_MOVE_ARG(WriteToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncWriteStream::executor_type),+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),-        token, static_cast<DynamicBuffer_v1&&>(buffers),-        transfer_all()))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),-      token, static_cast<DynamicBuffer_v1&&>(buffers),-      transfer_all());-}+        declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        transfer_all())));  /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -1096,7 +1052,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1115,34 +1071,25 @@ template <typename AsyncWriteStream,     typename DynamicBuffer_v1, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) WriteToken-        = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v1&& buffers,+      std::size_t)) WriteToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s,+    ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,     CompletionCondition completion_condition,-    WriteToken&& token-      = default_completion_token_t<typename AsyncWriteStream::executor_type>(),-    constraint_t<-      is_dynamic_buffer_v1<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      !is_dynamic_buffer_v2<decay_t<DynamicBuffer_v1>>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(WriteToken) token,+    typename constraint<+      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0,+    typename constraint<+      !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),-        token, static_cast<DynamicBuffer_v1&&>(buffers),-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),-      token, static_cast<DynamicBuffer_v1&&>(buffers),-      static_cast<CompletionCondition&&>(completion_condition));-}+        declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -1188,7 +1135,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1207,24 +1154,17 @@ template <typename AsyncWriteStream, typename Allocator,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       std::size_t)) WriteToken-        = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,-    WriteToken&& token-      = default_completion_token_t<typename AsyncWriteStream::executor_type>(),-    constraint_t<-      !is_completion_condition<decay_t<WriteToken>>::value-    > = 0)-  -> decltype(-    async_initiate<WriteToken,-      void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),-        token, basic_streambuf_ref<Allocator>(b), transfer_all()))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),-      token, basic_streambuf_ref<Allocator>(b), transfer_all());-}+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncWriteStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,+    ASIO_MOVE_ARG(WriteToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncWriteStream::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_write(s, basic_streambuf_ref<Allocator>(b),+        ASIO_MOVE_CAST(WriteToken)(token))));  /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -1281,7 +1221,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1300,28 +1240,16 @@ template <typename AsyncWriteStream,     typename Allocator, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) WriteToken-        = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,+      std::size_t)) WriteToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,     CompletionCondition completion_condition,-    WriteToken&& token-      = default_completion_token_t<typename AsyncWriteStream::executor_type>(),-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(-    async_initiate<WriteToken,-      void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>>(),-        token, basic_streambuf_ref<Allocator>(b),-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_dynbuf_v1<AsyncWriteStream>(s),-      token, basic_streambuf_ref<Allocator>(b),-      static_cast<CompletionCondition&&>(completion_condition));-}+    ASIO_MOVE_ARG(WriteToken) token)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((+    async_write(s, basic_streambuf_ref<Allocator>(b),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition),+        ASIO_MOVE_CAST(WriteToken)(token))));  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -1370,7 +1298,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1389,29 +1317,23 @@ template <typename AsyncWriteStream, typename DynamicBuffer_v2,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,       std::size_t)) WriteToken-        = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,-    WriteToken&& token-      = default_completion_token_t<typename AsyncWriteStream::executor_type>(),-    constraint_t<+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncWriteStream::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,+    ASIO_MOVE_ARG(WriteToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncWriteStream::executor_type),+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0,-    constraint_t<-      !is_completion_condition<decay_t<WriteToken>>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>>(),-        token, static_cast<DynamicBuffer_v2&&>(buffers),-        transfer_all()))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),-      token, static_cast<DynamicBuffer_v2&&>(buffers),-      transfer_all());-}+        declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        transfer_all())));  /// Start an asynchronous operation to write a certain amount of data to a /// stream.@@ -1470,7 +1392,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -1489,31 +1411,21 @@ template <typename AsyncWriteStream,     typename DynamicBuffer_v2, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) WriteToken-        = default_completion_token_t<typename AsyncWriteStream::executor_type>>-inline auto async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,+      std::size_t)) WriteToken>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,     CompletionCondition completion_condition,-    WriteToken&& token-      = default_completion_token_t<typename AsyncWriteStream::executor_type>(),-    constraint_t<+    ASIO_MOVE_ARG(WriteToken) token,+    typename constraint<       is_dynamic_buffer_v2<DynamicBuffer_v2>::value-    > = 0,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+    >::type = 0)+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(-        declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>>(),-        token, static_cast<DynamicBuffer_v2&&>(buffers),-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_dynbuf_v2<AsyncWriteStream>(s),-      token, static_cast<DynamicBuffer_v2&&>(buffers),-      static_cast<CompletionCondition&&>(completion_condition));-}+        declval<detail::initiate_async_write_dynbuf_v2<AsyncWriteStream> >(),+        token, ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  /*@}*/ 
link/modules/asio-standalone/asio/include/asio/write_at.hpp view
@@ -2,7 +2,7 @@ // write_at.hpp // ~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -187,10 +187,7 @@     typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d,     uint64_t offset, const ConstBufferSequence& buffers,-    CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition);  /// Write a certain amount of data at a specified offset before returning. /**@@ -238,10 +235,7 @@     typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d,     uint64_t offset, const ConstBufferSequence& buffers,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    CompletionCondition completion_condition, asio::error_code& ec);  #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -354,10 +348,7 @@ template <typename SyncRandomAccessWriteDevice, typename Allocator,     typename CompletionCondition> std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset,-    basic_streambuf<Allocator>& b, CompletionCondition completion_condition,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+    basic_streambuf<Allocator>& b, CompletionCondition completion_condition);  /// Write a certain amount of data at a specified offset before returning. /**@@ -400,12 +391,9 @@  */ template <typename SyncRandomAccessWriteDevice, typename Allocator,     typename CompletionCondition>-std::size_t write_at(SyncRandomAccessWriteDevice& d,-    uint64_t offset, basic_streambuf<Allocator>& b,-    CompletionCondition completion_condition, asio::error_code& ec,-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0);+std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset,+    basic_streambuf<Allocator>& b, CompletionCondition completion_condition,+    asio::error_code& ec);  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)@@ -468,7 +456,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -495,27 +483,22 @@  */ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) WriteToken = default_completion_token_t<-        typename AsyncRandomAccessWriteDevice::executor_type>>-inline auto async_write_at(AsyncRandomAccessWriteDevice& d,-    uint64_t offset, const ConstBufferSequence& buffers,-    WriteToken&& token = default_completion_token_t<-      typename AsyncRandomAccessWriteDevice::executor_type>(),-    constraint_t<-      !is_completion_condition<WriteToken>::value-    > = 0)-  -> decltype(+      std::size_t)) WriteToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncRandomAccessWriteDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,+    const ConstBufferSequence& buffers,+    ASIO_MOVE_ARG(WriteToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncRandomAccessWriteDevice::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(         declval<detail::initiate_async_write_at<-          AsyncRandomAccessWriteDevice>>(),-        token, offset, buffers, transfer_all()))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),-      token, offset, buffers, transfer_all());-}+          AsyncRandomAccessWriteDevice> >(),+        token, offset, buffers, transfer_all())));  /// Start an asynchronous operation to write a certain amount of data at the /// specified offset.@@ -579,7 +562,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -608,30 +591,24 @@ template <typename AsyncRandomAccessWriteDevice,     typename ConstBufferSequence, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) WriteToken = default_completion_token_t<-        typename AsyncRandomAccessWriteDevice::executor_type>>-inline auto async_write_at(AsyncRandomAccessWriteDevice& d,+      std::size_t)) WriteToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncRandomAccessWriteDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,     uint64_t offset, const ConstBufferSequence& buffers,     CompletionCondition completion_condition,-    WriteToken&& token = default_completion_token_t<-      typename AsyncRandomAccessWriteDevice::executor_type>(),-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(WriteToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncRandomAccessWriteDevice::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(         declval<detail::initiate_async_write_at<-          AsyncRandomAccessWriteDevice>>(),+          AsyncRandomAccessWriteDevice> >(),         token, offset, buffers,-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_at<AsyncRandomAccessWriteDevice>(d),-      token, offset, buffers,-      static_cast<CompletionCondition&&>(completion_condition));-}+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  #if !defined(ASIO_NO_EXTENSIONS) #if !defined(ASIO_NO_IOSTREAM)@@ -682,7 +659,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -700,28 +677,22 @@  */ template <typename AsyncRandomAccessWriteDevice, typename Allocator,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) WriteToken = default_completion_token_t<-        typename AsyncRandomAccessWriteDevice::executor_type>>-inline auto async_write_at(AsyncRandomAccessWriteDevice& d,+      std::size_t)) WriteToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncRandomAccessWriteDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d,     uint64_t offset, basic_streambuf<Allocator>& b,-    WriteToken&& token = default_completion_token_t<-      typename AsyncRandomAccessWriteDevice::executor_type>(),-    constraint_t<-      !is_completion_condition<WriteToken>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(WriteToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncRandomAccessWriteDevice::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(         declval<detail::initiate_async_write_at_streambuf<-          AsyncRandomAccessWriteDevice>>(),-        token, offset, &b, transfer_all()))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_at_streambuf<-        AsyncRandomAccessWriteDevice>(d),-      token, offset, &b, transfer_all());-}+          AsyncRandomAccessWriteDevice> >(),+        token, offset, &b, transfer_all())));  /// Start an asynchronous operation to write a certain amount of data at the /// specified offset.@@ -783,7 +754,7 @@  * Regardless of whether the asynchronous operation completes immediately or  * not, the completion handler will not be invoked from within this function.  * On immediate completion, invocation of the handler will be performed in a- * manner equivalent to using asio::async_immediate().+ * manner equivalent to using asio::post().  *  * @par Completion Signature  * @code void(asio::error_code, std::size_t) @endcode@@ -802,30 +773,23 @@ template <typename AsyncRandomAccessWriteDevice,     typename Allocator, typename CompletionCondition,     ASIO_COMPLETION_TOKEN_FOR(void (asio::error_code,-      std::size_t)) WriteToken = default_completion_token_t<-        typename AsyncRandomAccessWriteDevice::executor_type>>-inline auto async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,+      std::size_t)) WriteToken+        ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(+          typename AsyncRandomAccessWriteDevice::executor_type)>+ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(WriteToken,+    void (asio::error_code, std::size_t))+async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,     basic_streambuf<Allocator>& b, CompletionCondition completion_condition,-    WriteToken&& token = default_completion_token_t<-      typename AsyncRandomAccessWriteDevice::executor_type>(),-    constraint_t<-      is_completion_condition<CompletionCondition>::value-    > = 0)-  -> decltype(+    ASIO_MOVE_ARG(WriteToken) token+      ASIO_DEFAULT_COMPLETION_TOKEN(+        typename AsyncRandomAccessWriteDevice::executor_type))+  ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((     async_initiate<WriteToken,       void (asio::error_code, std::size_t)>(         declval<detail::initiate_async_write_at_streambuf<-          AsyncRandomAccessWriteDevice>>(),+          AsyncRandomAccessWriteDevice> >(),         token, offset, &b,-        static_cast<CompletionCondition&&>(completion_condition)))-{-  return async_initiate<WriteToken,-    void (asio::error_code, std::size_t)>(-      detail::initiate_async_write_at_streambuf<-        AsyncRandomAccessWriteDevice>(d),-      token, offset, &b,-      static_cast<CompletionCondition&&>(completion_condition));-}+        ASIO_MOVE_CAST(CompletionCondition)(completion_condition))));  #endif // !defined(ASIO_NO_IOSTREAM) #endif // !defined(ASIO_NO_EXTENSIONS)
link/modules/asio-standalone/asio/include/asio/yield.hpp view
@@ -2,7 +2,7 @@ // yield.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
+ link/modules/asio-standalone/asio/src/examples/cpp03/chat/chat_message.hpp view
@@ -0,0 +1,96 @@+//+// chat_message.hpp+// ~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef CHAT_MESSAGE_HPP+#define CHAT_MESSAGE_HPP++#include <cstdio>+#include <cstdlib>+#include <cstring>++class chat_message+{+public:+  enum+  {+    header_length = 4,+    max_body_length = 512+  };++  chat_message()+    : body_length_(0)+  {+  }++  const char* data() const+  {+    return data_;+  }++  char* data()+  {+    return data_;+  }++  size_t length() const+  {+    return header_length + body_length_;+  }++  const char* body() const+  {+    return data_ + header_length;+  }++  char* body()+  {+    return data_ + header_length;+  }++  size_t body_length() const+  {+    return body_length_;+  }++  void body_length(size_t new_length)+  {+    body_length_ = new_length;+    if (body_length_ > max_body_length)+      body_length_ = max_body_length;+  }++  bool decode_header()+  {+    using namespace std; // For strncat and atoi.+    char header[header_length + 1] = "";+    strncat(header, data_, header_length);+    body_length_ = atoi(header);+    if (body_length_ > max_body_length)+    {+      body_length_ = 0;+      return false;+    }+    return true;+  }++  void encode_header()+  {+    using namespace std; // For sprintf and memcpy.+    char header[header_length + 1] = "";+    sprintf(header, "%4d", static_cast<int>(body_length_));+    memcpy(data_, header, header_length);+  }++private:+  char data_[header_length + max_body_length];+  size_t body_length_;+};++#endif // CHAT_MESSAGE_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/connection.hpp view
@@ -0,0 +1,83 @@+//+// connection.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_CONNECTION_HPP+#define HTTP_CONNECTION_HPP++#include <asio.hpp>+#include <boost/array.hpp>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include <boost/enable_shared_from_this.hpp>+#include "reply.hpp"+#include "request.hpp"+#include "request_handler.hpp"+#include "request_parser.hpp"++namespace http {+namespace server {++class connection_manager;++/// Represents a single connection from a client.+class connection+  : public boost::enable_shared_from_this<connection>,+    private boost::noncopyable+{+public:+  /// Construct a connection with the given io_context.+  explicit connection(asio::io_context& io_context,+      connection_manager& manager, request_handler& handler);++  /// Get the socket associated with the connection.+  asio::ip::tcp::socket& socket();++  /// Start the first asynchronous operation for the connection.+  void start();++  /// Stop all asynchronous operations associated with the connection.+  void stop();++private:+  /// Handle completion of a read operation.+  void handle_read(const asio::error_code& e,+      std::size_t bytes_transferred);++  /// Handle completion of a write operation.+  void handle_write(const asio::error_code& e);++  /// Socket for the connection.+  asio::ip::tcp::socket socket_;++  /// The manager for this connection.+  connection_manager& connection_manager_;++  /// The handler used to process the incoming request.+  request_handler& request_handler_;++  /// Buffer for incoming data.+  boost::array<char, 8192> buffer_;++  /// The incoming request.+  request request_;++  /// The parser for the incoming request.+  request_parser request_parser_;++  /// The reply to be sent back to the client.+  reply reply_;+};++typedef boost::shared_ptr<connection> connection_ptr;++} // namespace server+} // namespace http++#endif // HTTP_CONNECTION_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/connection_manager.hpp view
@@ -0,0 +1,44 @@+//+// connection_manager.hpp+// ~~~~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_CONNECTION_MANAGER_HPP+#define HTTP_CONNECTION_MANAGER_HPP++#include <set>+#include <boost/noncopyable.hpp>+#include "connection.hpp"++namespace http {+namespace server {++/// Manages open connections so that they may be cleanly stopped when the server+/// needs to shut down.+class connection_manager+  : private boost::noncopyable+{+public:+  /// Add the specified connection to the manager and start it.+  void start(connection_ptr c);++  /// Stop the specified connection.+  void stop(connection_ptr c);++  /// Stop all connections.+  void stop_all();++private:+  /// The managed connections.+  std::set<connection_ptr> connections_;+};++} // namespace server+} // namespace http++#endif // HTTP_CONNECTION_MANAGER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/header.hpp view
@@ -0,0 +1,28 @@+//+// header.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_HEADER_HPP+#define HTTP_HEADER_HPP++#include <string>++namespace http {+namespace server {++struct header+{+  std::string name;+  std::string value;+};++} // namespace server+} // namespace http++#endif // HTTP_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/mime_types.hpp view
@@ -0,0 +1,27 @@+//+// mime_types.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_MIME_TYPES_HPP+#define HTTP_MIME_TYPES_HPP++#include <string>++namespace http {+namespace server {+namespace mime_types {++/// Convert a file extension into a MIME type.+std::string extension_to_type(const std::string& extension);++} // namespace mime_types+} // namespace server+} // namespace http++#endif // HTTP_MIME_TYPES_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/reply.hpp view
@@ -0,0 +1,64 @@+//+// reply.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_REPLY_HPP+#define HTTP_REPLY_HPP++#include <string>+#include <vector>+#include <asio.hpp>+#include "header.hpp"++namespace http {+namespace server {++/// A reply to be sent to a client.+struct reply+{+  /// The status of the reply.+  enum status_type+  {+    ok = 200,+    created = 201,+    accepted = 202,+    no_content = 204,+    multiple_choices = 300,+    moved_permanently = 301,+    moved_temporarily = 302,+    not_modified = 304,+    bad_request = 400,+    unauthorized = 401,+    forbidden = 403,+    not_found = 404,+    internal_server_error = 500,+    not_implemented = 501,+    bad_gateway = 502,+    service_unavailable = 503+  } status;++  /// The headers to be included in the reply.+  std::vector<header> headers;++  /// The content to be sent in the reply.+  std::string content;++  /// Convert the reply into a vector of buffers. The buffers do not own the+  /// underlying memory blocks, therefore the reply object must remain valid and+  /// not be changed until the write operation has completed.+  std::vector<asio::const_buffer> to_buffers();++  /// Get a stock reply.+  static reply stock_reply(status_type status);+};++} // namespace server+} // namespace http++#endif // HTTP_REPLY_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request.hpp view
@@ -0,0 +1,34 @@+//+// request.hpp+// ~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_REQUEST_HPP+#define HTTP_REQUEST_HPP++#include <string>+#include <vector>+#include "header.hpp"++namespace http {+namespace server {++/// A request received from a client.+struct request+{+  std::string method;+  std::string uri;+  int http_version_major;+  int http_version_minor;+  std::vector<header> headers;+};++} // namespace server+} // namespace http++#endif // HTTP_REQUEST_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request_handler.hpp view
@@ -0,0 +1,46 @@+//+// request_handler.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_REQUEST_HANDLER_HPP+#define HTTP_REQUEST_HANDLER_HPP++#include <string>+#include <boost/noncopyable.hpp>++namespace http {+namespace server {++struct reply;+struct request;++/// The common handler for all incoming requests.+class request_handler+  : private boost::noncopyable+{+public:+  /// Construct with a directory containing files to be served.+  explicit request_handler(const std::string& doc_root);++  /// Handle a request and produce a reply.+  void handle_request(const request& req, reply& rep);++private:+  /// The directory containing the files to be served.+  std::string doc_root_;++  /// Perform URL-decoding on a string. Returns false if the encoding was+  /// invalid.+  static bool url_decode(const std::string& in, std::string& out);+};++} // namespace server+} // namespace http++#endif // HTTP_REQUEST_HANDLER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/request_parser.hpp view
@@ -0,0 +1,95 @@+//+// request_parser.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_REQUEST_PARSER_HPP+#define HTTP_REQUEST_PARSER_HPP++#include <boost/logic/tribool.hpp>+#include <boost/tuple/tuple.hpp>++namespace http {+namespace server {++struct request;++/// Parser for incoming requests.+class request_parser+{+public:+  /// Construct ready to parse the request method.+  request_parser();++  /// Reset to initial parser state.+  void reset();++  /// Parse some data. The tribool return value is true when a complete request+  /// has been parsed, false if the data is invalid, indeterminate when more+  /// data is required. The InputIterator return value indicates how much of the+  /// input has been consumed.+  template <typename InputIterator>+  boost::tuple<boost::tribool, InputIterator> parse(request& req,+      InputIterator begin, InputIterator end)+  {+    while (begin != end)+    {+      boost::tribool result = consume(req, *begin++);+      if (result || !result)+        return boost::make_tuple(result, begin);+    }+    boost::tribool result = boost::indeterminate;+    return boost::make_tuple(result, begin);+  }++private:+  /// Handle the next character of input.+  boost::tribool consume(request& req, char input);++  /// Check if a byte is an HTTP character.+  static bool is_char(int c);++  /// Check if a byte is an HTTP control character.+  static bool is_ctl(int c);++  /// Check if a byte is defined as an HTTP tspecial character.+  static bool is_tspecial(int c);++  /// Check if a byte is a digit.+  static bool is_digit(int c);++  /// The current state of the parser.+  enum state+  {+    method_start,+    method,+    uri,+    http_version_h,+    http_version_t_1,+    http_version_t_2,+    http_version_p,+    http_version_slash,+    http_version_major_start,+    http_version_major,+    http_version_minor_start,+    http_version_minor,+    expecting_newline_1,+    header_line_start,+    header_lws,+    header_name,+    space_before_header_value,+    header_value,+    expecting_newline_2,+    expecting_newline_3+  } state_;+};++} // namespace server+} // namespace http++#endif // HTTP_REQUEST_PARSER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server/server.hpp view
@@ -0,0 +1,69 @@+//+// server.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER_HPP+#define HTTP_SERVER_HPP++#include <asio.hpp>+#include <string>+#include <boost/noncopyable.hpp>+#include "connection.hpp"+#include "connection_manager.hpp"+#include "request_handler.hpp"++namespace http {+namespace server {++/// The top-level class of the HTTP server.+class server+  : private boost::noncopyable+{+public:+  /// Construct the server to listen on the specified TCP address and port, and+  /// serve up files from the given directory.+  explicit server(const std::string& address, const std::string& port,+      const std::string& doc_root);++  /// Run the server's io_context loop.+  void run();++private:+  /// Initiate an asynchronous accept operation.+  void start_accept();++  /// Handle completion of an asynchronous accept operation.+  void handle_accept(const asio::error_code& e);++  /// Handle a request to stop the server.+  void handle_stop();++  /// The io_context used to perform asynchronous operations.+  asio::io_context io_context_;++  /// The signal_set is used to register for process termination notifications.+  asio::signal_set signals_;++  /// Acceptor used to listen for incoming connections.+  asio::ip::tcp::acceptor acceptor_;++  /// The connection manager which owns all live connections.+  connection_manager connection_manager_;++  /// The next connection to be accepted.+  connection_ptr new_connection_;++  /// The handler for all incoming requests.+  request_handler request_handler_;+};++} // namespace server+} // namespace http++#endif // HTTP_SERVER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/connection.hpp view
@@ -0,0 +1,75 @@+//+// connection.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER2_CONNECTION_HPP+#define HTTP_SERVER2_CONNECTION_HPP++#include <asio.hpp>+#include <boost/array.hpp>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include <boost/enable_shared_from_this.hpp>+#include "reply.hpp"+#include "request.hpp"+#include "request_handler.hpp"+#include "request_parser.hpp"++namespace http {+namespace server2 {++/// Represents a single connection from a client.+class connection+  : public boost::enable_shared_from_this<connection>,+    private boost::noncopyable+{+public:+  /// Construct a connection with the given io_context.+  explicit connection(asio::io_context& io_context,+      request_handler& handler);++  /// Get the socket associated with the connection.+  asio::ip::tcp::socket& socket();++  /// Start the first asynchronous operation for the connection.+  void start();++private:+  /// Handle completion of a read operation.+  void handle_read(const asio::error_code& e,+      std::size_t bytes_transferred);++  /// Handle completion of a write operation.+  void handle_write(const asio::error_code& e);++  /// Socket for the connection.+  asio::ip::tcp::socket socket_;++  /// The handler used to process the incoming request.+  request_handler& request_handler_;++  /// Buffer for incoming data.+  boost::array<char, 8192> buffer_;++  /// The incoming request.+  request request_;++  /// The parser for the incoming request.+  request_parser request_parser_;++  /// The reply to be sent back to the client.+  reply reply_;+};++typedef boost::shared_ptr<connection> connection_ptr;++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_CONNECTION_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/header.hpp view
@@ -0,0 +1,28 @@+//+// header.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER2_HEADER_HPP+#define HTTP_SERVER2_HEADER_HPP++#include <string>++namespace http {+namespace server2 {++struct header+{+  std::string name;+  std::string value;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/io_context_pool.hpp view
@@ -0,0 +1,58 @@+//+// io_context_pool.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER2_IO_SERVICE_POOL_HPP+#define HTTP_SERVER2_IO_SERVICE_POOL_HPP++#include <asio.hpp>+#include <list>+#include <vector>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>++namespace http {+namespace server2 {++/// A pool of io_context objects.+class io_context_pool+  : private boost::noncopyable+{+public:+  /// Construct the io_context pool.+  explicit io_context_pool(std::size_t pool_size);++  /// Run all io_context objects in the pool.+  void run();++  /// Stop all io_context objects in the pool.+  void stop();++  /// Get an io_context to use.+  asio::io_context& get_io_context();++private:+  typedef boost::shared_ptr<asio::io_context> io_context_ptr;+  typedef asio::executor_work_guard<+    asio::io_context::executor_type> io_context_work;++  /// The pool of io_contexts.+  std::vector<io_context_ptr> io_contexts_;++  /// The work that keeps the io_contexts running.+  std::list<io_context_work> work_;++  /// The next io_context to use for a connection.+  std::size_t next_io_context_;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_IO_SERVICE_POOL_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/mime_types.hpp view
@@ -0,0 +1,27 @@+//+// mime_types.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER2_MIME_TYPES_HPP+#define HTTP_SERVER2_MIME_TYPES_HPP++#include <string>++namespace http {+namespace server2 {+namespace mime_types {++/// Convert a file extension into a MIME type.+std::string extension_to_type(const std::string& extension);++} // namespace mime_types+} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_MIME_TYPES_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/reply.hpp view
@@ -0,0 +1,64 @@+//+// reply.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER2_REPLY_HPP+#define HTTP_SERVER2_REPLY_HPP++#include <string>+#include <vector>+#include <asio.hpp>+#include "header.hpp"++namespace http {+namespace server2 {++/// A reply to be sent to a client.+struct reply+{+  /// The status of the reply.+  enum status_type+  {+    ok = 200,+    created = 201,+    accepted = 202,+    no_content = 204,+    multiple_choices = 300,+    moved_permanently = 301,+    moved_temporarily = 302,+    not_modified = 304,+    bad_request = 400,+    unauthorized = 401,+    forbidden = 403,+    not_found = 404,+    internal_server_error = 500,+    not_implemented = 501,+    bad_gateway = 502,+    service_unavailable = 503+  } status;++  /// The headers to be included in the reply.+  std::vector<header> headers;++  /// The content to be sent in the reply.+  std::string content;++  /// Convert the reply into a vector of buffers. The buffers do not own the+  /// underlying memory blocks, therefore the reply object must remain valid and+  /// not be changed until the write operation has completed.+  std::vector<asio::const_buffer> to_buffers();++  /// Get a stock reply.+  static reply stock_reply(status_type status);+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_REPLY_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request.hpp view
@@ -0,0 +1,34 @@+//+// request.hpp+// ~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER2_REQUEST_HPP+#define HTTP_SERVER2_REQUEST_HPP++#include <string>+#include <vector>+#include "header.hpp"++namespace http {+namespace server2 {++/// A request received from a client.+struct request+{+  std::string method;+  std::string uri;+  int http_version_major;+  int http_version_minor;+  std::vector<header> headers;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_REQUEST_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request_handler.hpp view
@@ -0,0 +1,46 @@+//+// request_handler.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER2_REQUEST_HANDLER_HPP+#define HTTP_SERVER2_REQUEST_HANDLER_HPP++#include <string>+#include <boost/noncopyable.hpp>++namespace http {+namespace server2 {++struct reply;+struct request;++/// The common handler for all incoming requests.+class request_handler+  : private boost::noncopyable+{+public:+  /// Construct with a directory containing files to be served.+  explicit request_handler(const std::string& doc_root);++  /// Handle a request and produce a reply.+  void handle_request(const request& req, reply& rep);++private:+  /// The directory containing the files to be served.+  std::string doc_root_;++  /// Perform URL-decoding on a string. Returns false if the encoding was+  /// invalid.+  static bool url_decode(const std::string& in, std::string& out);+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_REQUEST_HANDLER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/request_parser.hpp view
@@ -0,0 +1,95 @@+//+// request_parser.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER2_REQUEST_PARSER_HPP+#define HTTP_SERVER2_REQUEST_PARSER_HPP++#include <boost/logic/tribool.hpp>+#include <boost/tuple/tuple.hpp>++namespace http {+namespace server2 {++struct request;++/// Parser for incoming requests.+class request_parser+{+public:+  /// Construct ready to parse the request method.+  request_parser();++  /// Reset to initial parser state.+  void reset();++  /// Parse some data. The tribool return value is true when a complete request+  /// has been parsed, false if the data is invalid, indeterminate when more+  /// data is required. The InputIterator return value indicates how much of the+  /// input has been consumed.+  template <typename InputIterator>+  boost::tuple<boost::tribool, InputIterator> parse(request& req,+      InputIterator begin, InputIterator end)+  {+    while (begin != end)+    {+      boost::tribool result = consume(req, *begin++);+      if (result || !result)+        return boost::make_tuple(result, begin);+    }+    boost::tribool result = boost::indeterminate;+    return boost::make_tuple(result, begin);+  }++private:+  /// Handle the next character of input.+  boost::tribool consume(request& req, char input);++  /// Check if a byte is an HTTP character.+  static bool is_char(int c);++  /// Check if a byte is an HTTP control character.+  static bool is_ctl(int c);++  /// Check if a byte is defined as an HTTP tspecial character.+  static bool is_tspecial(int c);++  /// Check if a byte is a digit.+  static bool is_digit(int c);++  /// The current state of the parser.+  enum state+  {+    method_start,+    method,+    uri,+    http_version_h,+    http_version_t_1,+    http_version_t_2,+    http_version_p,+    http_version_slash,+    http_version_major_start,+    http_version_major,+    http_version_minor_start,+    http_version_minor,+    expecting_newline_1,+    header_line_start,+    header_lws,+    header_name,+    space_before_header_value,+    header_value,+    expecting_newline_2,+    expecting_newline_3+  } state_;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_REQUEST_PARSER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server2/server.hpp view
@@ -0,0 +1,68 @@+//+// server.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER2_SERVER_HPP+#define HTTP_SERVER2_SERVER_HPP++#include <asio.hpp>+#include <string>+#include <vector>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include "connection.hpp"+#include "io_context_pool.hpp"+#include "request_handler.hpp"++namespace http {+namespace server2 {++/// The top-level class of the HTTP server.+class server+  : private boost::noncopyable+{+public:+  /// Construct the server to listen on the specified TCP address and port, and+  /// serve up files from the given directory.+  explicit server(const std::string& address, const std::string& port,+      const std::string& doc_root, std::size_t io_context_pool_size);++  /// Run the server's io_context loop.+  void run();++private:+  /// Initiate an asynchronous accept operation.+  void start_accept();++  /// Handle completion of an asynchronous accept operation.+  void handle_accept(const asio::error_code& e);++  /// Handle a request to stop the server.+  void handle_stop();++  /// The pool of io_context objects used to perform asynchronous operations.+  io_context_pool io_context_pool_;++  /// The signal_set is used to register for process termination notifications.+  asio::signal_set signals_;++  /// Acceptor used to listen for incoming connections.+  asio::ip::tcp::acceptor acceptor_;++  /// The next connection to be accepted.+  connection_ptr new_connection_;++  /// The handler for all incoming requests.+  request_handler request_handler_;+};++} // namespace server2+} // namespace http++#endif // HTTP_SERVER2_SERVER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/connection.hpp view
@@ -0,0 +1,78 @@+//+// connection.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER3_CONNECTION_HPP+#define HTTP_SERVER3_CONNECTION_HPP++#include <asio.hpp>+#include <boost/array.hpp>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include <boost/enable_shared_from_this.hpp>+#include "reply.hpp"+#include "request.hpp"+#include "request_handler.hpp"+#include "request_parser.hpp"++namespace http {+namespace server3 {++/// Represents a single connection from a client.+class connection+  : public boost::enable_shared_from_this<connection>,+    private boost::noncopyable+{+public:+  /// Construct a connection with the given io_context.+  explicit connection(asio::io_context& io_context,+      request_handler& handler);++  /// Get the socket associated with the connection.+  asio::ip::tcp::socket& socket();++  /// Start the first asynchronous operation for the connection.+  void start();++private:+  /// Handle completion of a read operation.+  void handle_read(const asio::error_code& e,+      std::size_t bytes_transferred);++  /// Handle completion of a write operation.+  void handle_write(const asio::error_code& e);++  /// Strand to ensure the connection's handlers are not called concurrently.+  asio::strand<asio::io_context::executor_type> strand_;++  /// Socket for the connection.+  asio::ip::tcp::socket socket_;++  /// The handler used to process the incoming request.+  request_handler& request_handler_;++  /// Buffer for incoming data.+  boost::array<char, 8192> buffer_;++  /// The incoming request.+  request request_;++  /// The parser for the incoming request.+  request_parser request_parser_;++  /// The reply to be sent back to the client.+  reply reply_;+};++typedef boost::shared_ptr<connection> connection_ptr;++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_CONNECTION_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/header.hpp view
@@ -0,0 +1,28 @@+//+// header.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER3_HEADER_HPP+#define HTTP_SERVER3_HEADER_HPP++#include <string>++namespace http {+namespace server3 {++struct header+{+  std::string name;+  std::string value;+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/mime_types.hpp view
@@ -0,0 +1,27 @@+//+// mime_types.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER3_MIME_TYPES_HPP+#define HTTP_SERVER3_MIME_TYPES_HPP++#include <string>++namespace http {+namespace server3 {+namespace mime_types {++/// Convert a file extension into a MIME type.+std::string extension_to_type(const std::string& extension);++} // namespace mime_types+} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_MIME_TYPES_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/reply.hpp view
@@ -0,0 +1,64 @@+//+// reply.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER3_REPLY_HPP+#define HTTP_SERVER3_REPLY_HPP++#include <string>+#include <vector>+#include <asio.hpp>+#include "header.hpp"++namespace http {+namespace server3 {++/// A reply to be sent to a client.+struct reply+{+  /// The status of the reply.+  enum status_type+  {+    ok = 200,+    created = 201,+    accepted = 202,+    no_content = 204,+    multiple_choices = 300,+    moved_permanently = 301,+    moved_temporarily = 302,+    not_modified = 304,+    bad_request = 400,+    unauthorized = 401,+    forbidden = 403,+    not_found = 404,+    internal_server_error = 500,+    not_implemented = 501,+    bad_gateway = 502,+    service_unavailable = 503+  } status;++  /// The headers to be included in the reply.+  std::vector<header> headers;++  /// The content to be sent in the reply.+  std::string content;++  /// Convert the reply into a vector of buffers. The buffers do not own the+  /// underlying memory blocks, therefore the reply object must remain valid and+  /// not be changed until the write operation has completed.+  std::vector<asio::const_buffer> to_buffers();++  /// Get a stock reply.+  static reply stock_reply(status_type status);+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_REPLY_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request.hpp view
@@ -0,0 +1,34 @@+//+// request.hpp+// ~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER3_REQUEST_HPP+#define HTTP_SERVER3_REQUEST_HPP++#include <string>+#include <vector>+#include "header.hpp"++namespace http {+namespace server3 {++/// A request received from a client.+struct request+{+  std::string method;+  std::string uri;+  int http_version_major;+  int http_version_minor;+  std::vector<header> headers;+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_REQUEST_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request_handler.hpp view
@@ -0,0 +1,46 @@+//+// request_handler.hpp+// ~~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER3_REQUEST_HANDLER_HPP+#define HTTP_SERVER3_REQUEST_HANDLER_HPP++#include <string>+#include <boost/noncopyable.hpp>++namespace http {+namespace server3 {++struct reply;+struct request;++/// The common handler for all incoming requests.+class request_handler+  : private boost::noncopyable+{+public:+  /// Construct with a directory containing files to be served.+  explicit request_handler(const std::string& doc_root);++  /// Handle a request and produce a reply.+  void handle_request(const request& req, reply& rep);++private:+  /// The directory containing the files to be served.+  std::string doc_root_;++  /// Perform URL-decoding on a string. Returns false if the encoding was+  /// invalid.+  static bool url_decode(const std::string& in, std::string& out);+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_REQUEST_HANDLER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/request_parser.hpp view
@@ -0,0 +1,95 @@+//+// request_parser.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER3_REQUEST_PARSER_HPP+#define HTTP_SERVER3_REQUEST_PARSER_HPP++#include <boost/logic/tribool.hpp>+#include <boost/tuple/tuple.hpp>++namespace http {+namespace server3 {++struct request;++/// Parser for incoming requests.+class request_parser+{+public:+  /// Construct ready to parse the request method.+  request_parser();++  /// Reset to initial parser state.+  void reset();++  /// Parse some data. The tribool return value is true when a complete request+  /// has been parsed, false if the data is invalid, indeterminate when more+  /// data is required. The InputIterator return value indicates how much of the+  /// input has been consumed.+  template <typename InputIterator>+  boost::tuple<boost::tribool, InputIterator> parse(request& req,+      InputIterator begin, InputIterator end)+  {+    while (begin != end)+    {+      boost::tribool result = consume(req, *begin++);+      if (result || !result)+        return boost::make_tuple(result, begin);+    }+    boost::tribool result = boost::indeterminate;+    return boost::make_tuple(result, begin);+  }++private:+  /// Handle the next character of input.+  boost::tribool consume(request& req, char input);++  /// Check if a byte is an HTTP character.+  static bool is_char(int c);++  /// Check if a byte is an HTTP control character.+  static bool is_ctl(int c);++  /// Check if a byte is defined as an HTTP tspecial character.+  static bool is_tspecial(int c);++  /// Check if a byte is a digit.+  static bool is_digit(int c);++  /// The current state of the parser.+  enum state+  {+    method_start,+    method,+    uri,+    http_version_h,+    http_version_t_1,+    http_version_t_2,+    http_version_p,+    http_version_slash,+    http_version_major_start,+    http_version_major,+    http_version_minor_start,+    http_version_minor,+    expecting_newline_1,+    header_line_start,+    header_lws,+    header_name,+    space_before_header_value,+    header_value,+    expecting_newline_2,+    expecting_newline_3+  } state_;+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_REQUEST_PARSER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server3/server.hpp view
@@ -0,0 +1,70 @@+//+// server.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER3_SERVER_HPP+#define HTTP_SERVER3_SERVER_HPP++#include <asio.hpp>+#include <string>+#include <vector>+#include <boost/noncopyable.hpp>+#include <boost/shared_ptr.hpp>+#include "connection.hpp"+#include "request_handler.hpp"++namespace http {+namespace server3 {++/// The top-level class of the HTTP server.+class server+  : private boost::noncopyable+{+public:+  /// Construct the server to listen on the specified TCP address and port, and+  /// serve up files from the given directory.+  explicit server(const std::string& address, const std::string& port,+      const std::string& doc_root, std::size_t thread_pool_size);++  /// Run the server's io_context loop.+  void run();++private:+  /// Initiate an asynchronous accept operation.+  void start_accept();++  /// Handle completion of an asynchronous accept operation.+  void handle_accept(const asio::error_code& e);++  /// Handle a request to stop the server.+  void handle_stop();++  /// The number of threads that will call io_context::run().+  std::size_t thread_pool_size_;++  /// The io_context used to perform asynchronous operations.+  asio::io_context io_context_;++  /// The signal_set is used to register for process termination notifications.+  asio::signal_set signals_;++  /// Acceptor used to listen for incoming connections.+  asio::ip::tcp::acceptor acceptor_;++  /// The next connection to be accepted.+  connection_ptr new_connection_;++  /// The handler for all incoming requests.+  request_handler request_handler_;+};++} // namespace server3+} // namespace http++#endif // HTTP_SERVER3_SERVER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/file_handler.hpp view
@@ -0,0 +1,44 @@+//+// file_handler.hpp+// ~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER4_FILE_HANDLER_HPP+#define HTTP_SERVER4_FILE_HANDLER_HPP++#include <string>++namespace http {+namespace server4 {++struct reply;+struct request;++/// The common handler for all incoming requests.+class file_handler+{+public:+  /// Construct with a directory containing files to be served.+  explicit file_handler(const std::string& doc_root);++  /// Handle a request and produce a reply.+  void operator()(const request& req, reply& rep);++private:+  /// The directory containing the files to be served.+  std::string doc_root_;++  /// Perform URL-decoding on a string. Returns false if the encoding was+  /// invalid.+  static bool url_decode(const std::string& in, std::string& out);+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_FILE_HANDLER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/header.hpp view
@@ -0,0 +1,28 @@+//+// header.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER4_HEADER_HPP+#define HTTP_SERVER4_HEADER_HPP++#include <string>++namespace http {+namespace server4 {++struct header+{+  std::string name;+  std::string value;+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/mime_types.hpp view
@@ -0,0 +1,27 @@+//+// mime_types.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER4_MIME_TYPES_HPP+#define HTTP_SERVER4_MIME_TYPES_HPP++#include <string>++namespace http {+namespace server4 {+namespace mime_types {++/// Convert a file extension into a MIME type.+std::string extension_to_type(const std::string& extension);++} // namespace mime_types+} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_MIME_TYPES_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/reply.hpp view
@@ -0,0 +1,64 @@+//+// reply.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER4_REPLY_HPP+#define HTTP_SERVER4_REPLY_HPP++#include <string>+#include <vector>+#include <asio.hpp>+#include "header.hpp"++namespace http {+namespace server4 {++/// A reply to be sent to a client.+struct reply+{+  /// The status of the reply.+  enum status_type+  {+    ok = 200,+    created = 201,+    accepted = 202,+    no_content = 204,+    multiple_choices = 300,+    moved_permanently = 301,+    moved_temporarily = 302,+    not_modified = 304,+    bad_request = 400,+    unauthorized = 401,+    forbidden = 403,+    not_found = 404,+    internal_server_error = 500,+    not_implemented = 501,+    bad_gateway = 502,+    service_unavailable = 503+  } status;++  /// The headers to be included in the reply.+  std::vector<header> headers;++  /// The content to be sent in the reply.+  std::string content;++  /// Convert the reply into a vector of buffers. The buffers do not own the+  /// underlying memory blocks, therefore the reply object must remain valid and+  /// not be changed until the write operation has completed.+  std::vector<asio::const_buffer> to_buffers();++  /// Get a stock reply.+  static reply stock_reply(status_type status);+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_REPLY_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/request.hpp view
@@ -0,0 +1,46 @@+//+// request.hpp+// ~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER4_REQUEST_HPP+#define HTTP_SERVER4_REQUEST_HPP++#include <string>+#include <vector>+#include "header.hpp"++namespace http {+namespace server4 {++/// A request received from a client.+struct request+{+  /// The request method, e.g. "GET", "POST".+  std::string method;++  /// The requested URI, such as a path to a file.+  std::string uri;++  /// Major version number, usually 1.+  int http_version_major;++  /// Minor version number, usually 0 or 1.+  int http_version_minor;++  /// The headers included with the request.+  std::vector<header> headers;++  /// The optional content sent with the request.+  std::string content;+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_REQUEST_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/request_parser.hpp view
@@ -0,0 +1,78 @@+//+// request_parser.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER4_REQUEST_PARSER_HPP+#define HTTP_SERVER4_REQUEST_PARSER_HPP++#include <string>+#include <boost/logic/tribool.hpp>+#include <boost/tuple/tuple.hpp>+#include <asio/coroutine.hpp>++namespace http {+namespace server4 {++struct request;++/// Parser for incoming requests.+class request_parser : asio::coroutine+{+public:+  /// Parse some data. The tribool return value is true when a complete request+  /// has been parsed, false if the data is invalid, indeterminate when more+  /// data is required. The InputIterator return value indicates how much of the+  /// input has been consumed.+  template <typename InputIterator>+  boost::tuple<boost::tribool, InputIterator> parse(request& req,+      InputIterator begin, InputIterator end)+  {+    while (begin != end)+    {+      boost::tribool result = consume(req, *begin++);+      if (result || !result)+        return boost::make_tuple(result, begin);+    }+    boost::tribool result = boost::indeterminate;+    return boost::make_tuple(result, begin);+  }++private:+  /// The name of the content length header.+  static std::string content_length_name_;++  /// Content length as decoded from headers. Defaults to 0.+  std::size_t content_length_;++  /// Handle the next character of input.+  boost::tribool consume(request& req, char input);++  /// Check if a byte is an HTTP character.+  static bool is_char(int c);++  /// Check if a byte is an HTTP control character.+  static bool is_ctl(int c);++  /// Check if a byte is defined as an HTTP tspecial character.+  static bool is_tspecial(int c);++  /// Check if a byte is a digit.+  static bool is_digit(int c);++  /// Check if two characters are equal, without regard to case.+  static bool tolower_compare(char a, char b);++  /// Check whether the two request header names match.+  bool headers_equal(const std::string& a, const std::string& b);+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_REQUEST_PARSER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/http/server4/server.hpp view
@@ -0,0 +1,73 @@+//+// server.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef HTTP_SERVER4_SERVER_HPP+#define HTTP_SERVER4_SERVER_HPP++#include <asio.hpp>+#include <string>+#include <boost/array.hpp>+#include <boost/function.hpp>+#include <boost/shared_ptr.hpp>+#include "request_parser.hpp"++namespace http {+namespace server4 {++struct request;+struct reply;++/// The top-level coroutine of the HTTP server.+class server : asio::coroutine+{+public:+  /// Construct the server to listen on the specified TCP address and port, and+  /// serve up files from the given directory.+  explicit server(asio::io_context& io_context,+      const std::string& address, const std::string& port,+      boost::function<void(const request&, reply&)> request_handler);++  /// Perform work associated with the server.+  void operator()(+      asio::error_code ec = asio::error_code(),+      std::size_t length = 0);++private:+  typedef asio::ip::tcp tcp;++  /// The user-supplied handler for all incoming requests.+  boost::function<void(const request&, reply&)> request_handler_;++  /// Acceptor used to listen for incoming connections.+  boost::shared_ptr<tcp::acceptor> acceptor_;++  /// The current connection from a client.+  boost::shared_ptr<tcp::socket> socket_;++  /// Buffer for incoming data.+  boost::shared_ptr<boost::array<char, 8192> > buffer_;++  /// The incoming request.+  boost::shared_ptr<request> request_;++  /// Whether the request is valid or not.+  boost::tribool valid_request_;++  /// The parser for the incoming request.+  request_parser request_parser_;++  /// The reply to be sent back to the client.+  boost::shared_ptr<reply> reply_;+};++} // namespace server4+} // namespace http++#endif // HTTP_SERVER4_SERVER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/icmp/icmp_header.hpp view
@@ -0,0 +1,94 @@+//+// icmp_header.hpp+// ~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef ICMP_HEADER_HPP+#define ICMP_HEADER_HPP++#include <istream>+#include <ostream>+#include <algorithm>++// ICMP header for both IPv4 and IPv6.+//+// The wire format of an ICMP header is:+// +// 0               8               16                             31+// +---------------+---------------+------------------------------+      ---+// |               |               |                              |       ^+// |     type      |     code      |          checksum            |       |+// |               |               |                              |       |+// +---------------+---------------+------------------------------+    8 bytes+// |                               |                              |       |+// |          identifier           |       sequence number        |       |+// |                               |                              |       v+// +-------------------------------+------------------------------+      ---++class icmp_header+{+public:+  enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4,+    redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12,+    timestamp_request = 13, timestamp_reply = 14, info_request = 15,+    info_reply = 16, address_request = 17, address_reply = 18 };++  icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }++  unsigned char type() const { return rep_[0]; }+  unsigned char code() const { return rep_[1]; }+  unsigned short checksum() const { return decode(2, 3); }+  unsigned short identifier() const { return decode(4, 5); }+  unsigned short sequence_number() const { return decode(6, 7); }++  void type(unsigned char n) { rep_[0] = n; }+  void code(unsigned char n) { rep_[1] = n; }+  void checksum(unsigned short n) { encode(2, 3, n); }+  void identifier(unsigned short n) { encode(4, 5, n); }+  void sequence_number(unsigned short n) { encode(6, 7, n); }++  friend std::istream& operator>>(std::istream& is, icmp_header& header)+    { return is.read(reinterpret_cast<char*>(header.rep_), 8); }++  friend std::ostream& operator<<(std::ostream& os, const icmp_header& header)+    { return os.write(reinterpret_cast<const char*>(header.rep_), 8); }++private:+  unsigned short decode(int a, int b) const+    { return (rep_[a] << 8) + rep_[b]; }++  void encode(int a, int b, unsigned short n)+  {+    rep_[a] = static_cast<unsigned char>(n >> 8);+    rep_[b] = static_cast<unsigned char>(n & 0xFF);+  }++  unsigned char rep_[8];+};++template <typename Iterator>+void compute_checksum(icmp_header& header,+    Iterator body_begin, Iterator body_end)+{+  unsigned int sum = (header.type() << 8) + header.code()+    + header.identifier() + header.sequence_number();++  Iterator body_iter = body_begin;+  while (body_iter != body_end)+  {+    sum += (static_cast<unsigned char>(*body_iter++) << 8);+    if (body_iter != body_end)+      sum += static_cast<unsigned char>(*body_iter++);+  }++  sum = (sum >> 16) + (sum & 0xFFFF);+  sum += (sum >> 16);+  header.checksum(static_cast<unsigned short>(~sum));+}++#endif // ICMP_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/icmp/ipv4_header.hpp view
@@ -0,0 +1,102 @@+//+// ipv4_header.hpp+// ~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef IPV4_HEADER_HPP+#define IPV4_HEADER_HPP++#include <algorithm>+#include <asio/ip/address_v4.hpp>++// Packet header for IPv4.+//+// The wire format of an IPv4 header is:+// +// 0               8               16                             31+// +-------+-------+---------------+------------------------------+      ---+// |       |       |               |                              |       ^+// |version|header |    type of    |    total length in bytes     |       |+// |  (4)  | length|    service    |                              |       |+// +-------+-------+---------------+-+-+-+------------------------+       |+// |                               | | | |                        |       |+// |        identification         |0|D|M|    fragment offset     |       |+// |                               | |F|F|                        |       |+// +---------------+---------------+-+-+-+------------------------+       |+// |               |               |                              |       |+// | time to live  |   protocol    |       header checksum        |   20 bytes+// |               |               |                              |       |+// +---------------+---------------+------------------------------+       |+// |                                                              |       |+// |                      source IPv4 address                     |       |+// |                                                              |       |+// +--------------------------------------------------------------+       |+// |                                                              |       |+// |                   destination IPv4 address                   |       |+// |                                                              |       v+// +--------------------------------------------------------------+      ---+// |                                                              |       ^+// |                                                              |       |+// /                        options (if any)                      /    0 - 40+// /                                                              /     bytes+// |                                                              |       |+// |                                                              |       v+// +--------------------------------------------------------------+      ---++class ipv4_header+{+public:+  ipv4_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }++  unsigned char version() const { return (rep_[0] >> 4) & 0xF; }+  unsigned short header_length() const { return (rep_[0] & 0xF) * 4; }+  unsigned char type_of_service() const { return rep_[1]; }+  unsigned short total_length() const { return decode(2, 3); }+  unsigned short identification() const { return decode(4, 5); }+  bool dont_fragment() const { return (rep_[6] & 0x40) != 0; }+  bool more_fragments() const { return (rep_[6] & 0x20) != 0; }+  unsigned short fragment_offset() const { return decode(6, 7) & 0x1FFF; }+  unsigned int time_to_live() const { return rep_[8]; }+  unsigned char protocol() const { return rep_[9]; }+  unsigned short header_checksum() const { return decode(10, 11); }++  asio::ip::address_v4 source_address() const+  {+    asio::ip::address_v4::bytes_type bytes+      = { { rep_[12], rep_[13], rep_[14], rep_[15] } };+    return asio::ip::address_v4(bytes);+  }++  asio::ip::address_v4 destination_address() const+  {+    asio::ip::address_v4::bytes_type bytes+      = { { rep_[16], rep_[17], rep_[18], rep_[19] } };+    return asio::ip::address_v4(bytes);+  }++  friend std::istream& operator>>(std::istream& is, ipv4_header& header)+  {+    is.read(reinterpret_cast<char*>(header.rep_), 20);+    if (header.version() != 4)+      is.setstate(std::ios::failbit);+    std::streamsize options_length = header.header_length() - 20;+    if (options_length < 0 || options_length > 40)+      is.setstate(std::ios::failbit);+    else+      is.read(reinterpret_cast<char*>(header.rep_) + 20, options_length);+    return is;+  }++private:+  unsigned short decode(int a, int b) const+    { return (rep_[a] << 8) + rep_[b]; }++  unsigned char rep_[60];+};++#endif // IPV4_HEADER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/porthopper/protocol.hpp view
@@ -0,0 +1,156 @@+//+// protocol.hpp+// ~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef PORTHOPPER_PROTOCOL_HPP+#define PORTHOPPER_PROTOCOL_HPP++#include <boost/array.hpp>+#include <asio.hpp>+#include <cstring>+#include <iomanip>+#include <string>+#include <strstream>++// This request is sent by the client to the server over a TCP connection.+// The client uses it to perform three functions:+// - To request that data start being sent to a given port.+// - To request that data is no longer sent to a given port.+// - To change the target port to another.+class control_request+{+public:+  // Construct an empty request. Used when receiving.+  control_request()+  {+  }++  // Create a request to start sending data to a given port.+  static const control_request start(unsigned short port)+  {+    return control_request(0, port);+  }++  // Create a request to stop sending data to a given port.+  static const control_request stop(unsigned short port)+  {+    return control_request(port, 0);+  }++  // Create a request to change the port that data is sent to.+  static const control_request change(+      unsigned short old_port, unsigned short new_port)+  {+    return control_request(old_port, new_port);+  }++  // Get the old port. Returns 0 for start requests.+  unsigned short old_port() const+  {+    std::istrstream is(data_, encoded_port_size);+    unsigned short port = 0;+    is >> std::setw(encoded_port_size) >> std::hex >> port;+    return port;+  }++  // Get the new port. Returns 0 for stop requests.+  unsigned short new_port() const+  {+    std::istrstream is(data_ + encoded_port_size, encoded_port_size);+    unsigned short port = 0;+    is >> std::setw(encoded_port_size) >> std::hex >> port;+    return port;+  }++  // Obtain buffers for reading from or writing to a socket.+  boost::array<asio::mutable_buffer, 1> to_buffers()+  {+    boost::array<asio::mutable_buffer, 1> buffers+      = { { asio::buffer(data_) } };+    return buffers;+  }++private:+  // Construct with specified old and new ports.+  control_request(unsigned short old_port_number,+      unsigned short new_port_number)+  {+    std::ostrstream os(data_, control_request_size);+    os << std::setw(encoded_port_size) << std::hex << old_port_number;+    os << std::setw(encoded_port_size) << std::hex << new_port_number;+  }++  // The length in bytes of a control_request and its components.+  enum+  {+    encoded_port_size = 4, // 16-bit port in hex.+    control_request_size = encoded_port_size * 2+  };++  // The encoded request data.+  char data_[control_request_size];+};++// This frame is sent from the server to subscribed clients over UDP.+class frame+{+public:+  // The maximum allowable length of the payload.+  enum { payload_size = 32 };++  // Construct an empty frame. Used when receiving.+  frame()+  {+  }++  // Construct a frame with specified frame number and payload.+  frame(unsigned long frame_number, const std::string& payload_data)+  {+    std::ostrstream os(data_, frame_size);+    os << std::setw(encoded_number_size) << std::hex << frame_number;+    os << std::setw(payload_size)+      << std::setfill(' ') << payload_data.substr(0, payload_size);+  }++  // Get the frame number.+  unsigned long number() const+  {+    std::istrstream is(data_, encoded_number_size);+    unsigned long frame_number = 0;+    is >> std::setw(encoded_number_size) >> std::hex >> frame_number;+    return frame_number;+  }++  // Get the payload data.+  const std::string payload() const+  {+    return std::string(data_ + encoded_number_size, payload_size);+  }++  // Obtain buffers for reading from or writing to a socket.+  boost::array<asio::mutable_buffer, 1> to_buffers()+  {+    boost::array<asio::mutable_buffer, 1> buffers+      = { { asio::buffer(data_) } };+    return buffers;+  }++private:+  // The length in bytes of a frame and its components.+  enum+  {+    encoded_number_size = 8, // Frame number in hex.+    frame_size = encoded_number_size + payload_size+  };++  // The encoded frame data.+  char data_[frame_size];+};++#endif // PORTHOPPER_PROTOCOL_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/serialization/connection.hpp view
@@ -0,0 +1,188 @@+//+// connection.hpp+// ~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef SERIALIZATION_CONNECTION_HPP+#define SERIALIZATION_CONNECTION_HPP++#include <asio.hpp>+#include <boost/archive/text_iarchive.hpp>+#include <boost/archive/text_oarchive.hpp>+#include <boost/bind/bind.hpp>+#include <boost/shared_ptr.hpp>+#include <boost/tuple/tuple.hpp>+#include <iomanip>+#include <string>+#include <sstream>+#include <vector>++namespace s11n_example {++/// The connection class provides serialization primitives on top of a socket.+/**+ * Each message sent using this class consists of:+ * @li An 8-byte header containing the length of the serialized data in+ * hexadecimal.+ * @li The serialized data.+ */+class connection+{+public:+  /// Constructor.+  connection(const asio::executor& ex)+    : socket_(ex)+  {+  }++  /// Get the underlying socket. Used for making a connection or for accepting+  /// an incoming connection.+  asio::ip::tcp::socket& socket()+  {+    return socket_;+  }++  /// Asynchronously write a data structure to the socket.+  template <typename T, typename Handler>+  void async_write(const T& t, Handler handler)+  {+    // Serialize the data first so we know how large it is.+    std::ostringstream archive_stream;+    boost::archive::text_oarchive archive(archive_stream);+    archive << t;+    outbound_data_ = archive_stream.str();++    // Format the header.+    std::ostringstream header_stream;+    header_stream << std::setw(header_length)+      << std::hex << outbound_data_.size();+    if (!header_stream || header_stream.str().size() != header_length)+    {+      // Something went wrong, inform the caller.+      asio::error_code error(asio::error::invalid_argument);+      asio::post(socket_.get_executor(), boost::bind(handler, error));+      return;+    }+    outbound_header_ = header_stream.str();++    // Write the serialized data to the socket. We use "gather-write" to send+    // both the header and the data in a single write operation.+    std::vector<asio::const_buffer> buffers;+    buffers.push_back(asio::buffer(outbound_header_));+    buffers.push_back(asio::buffer(outbound_data_));+    asio::async_write(socket_, buffers, handler);+  }++  /// Asynchronously read a data structure from the socket.+  template <typename T, typename Handler>+  void async_read(T& t, Handler handler)+  {+    // Issue a read operation to read exactly the number of bytes in a header.+    void (connection::*f)(+        const asio::error_code&,+        T&, boost::tuple<Handler>)+      = &connection::handle_read_header<T, Handler>;+    asio::async_read(socket_, asio::buffer(inbound_header_),+        boost::bind(f,+          this, asio::placeholders::error, boost::ref(t),+          boost::make_tuple(handler)));+  }++  /// Handle a completed read of a message header. The handler is passed using+  /// a tuple since boost::bind seems to have trouble binding a function object+  /// created using boost::bind as a parameter.+  template <typename T, typename Handler>+  void handle_read_header(const asio::error_code& e,+      T& t, boost::tuple<Handler> handler)+  {+    if (e)+    {+      boost::get<0>(handler)(e);+    }+    else+    {+      // Determine the length of the serialized data.+      std::istringstream is(std::string(inbound_header_, header_length));+      std::size_t inbound_data_size = 0;+      if (!(is >> std::hex >> inbound_data_size))+      {+        // Header doesn't seem to be valid. Inform the caller.+        asio::error_code error(asio::error::invalid_argument);+        boost::get<0>(handler)(error);+        return;+      }++      // Start an asynchronous call to receive the data.+      inbound_data_.resize(inbound_data_size);+      void (connection::*f)(+          const asio::error_code&,+          T&, boost::tuple<Handler>)+        = &connection::handle_read_data<T, Handler>;+      asio::async_read(socket_, asio::buffer(inbound_data_),+        boost::bind(f, this,+          asio::placeholders::error, boost::ref(t), handler));+    }+  }++  /// Handle a completed read of message data.+  template <typename T, typename Handler>+  void handle_read_data(const asio::error_code& e,+      T& t, boost::tuple<Handler> handler)+  {+    if (e)+    {+      boost::get<0>(handler)(e);+    }+    else+    {+      // Extract the data structure from the data just received.+      try+      {+        std::string archive_data(&inbound_data_[0], inbound_data_.size());+        std::istringstream archive_stream(archive_data);+        boost::archive::text_iarchive archive(archive_stream);+        archive >> t;+      }+      catch (std::exception& e)+      {+        // Unable to decode data.+        asio::error_code error(asio::error::invalid_argument);+        boost::get<0>(handler)(error);+        return;+      }++      // Inform caller that data has been received ok.+      boost::get<0>(handler)(e);+    }+  }++private:+  /// The underlying socket.+  asio::ip::tcp::socket socket_;++  /// The size of a fixed length header.+  enum { header_length = 8 };++  /// Holds an outbound header.+  std::string outbound_header_;++  /// Holds the outbound data.+  std::string outbound_data_;++  /// Holds an inbound header.+  char inbound_header_[header_length];++  /// Holds the inbound data.+  std::vector<char> inbound_data_;+};++typedef boost::shared_ptr<connection> connection_ptr;++} // namespace s11n_example++#endif // SERIALIZATION_CONNECTION_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/serialization/stock.hpp view
@@ -0,0 +1,50 @@+//+// stock.hpp+// ~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef SERIALIZATION_STOCK_HPP+#define SERIALIZATION_STOCK_HPP++#include <string>++namespace s11n_example {++/// Structure to hold information about a single stock.+struct stock+{+  std::string code;+  std::string name;+  double open_price;+  double high_price;+  double low_price;+  double last_price;+  double buy_price;+  int buy_quantity;+  double sell_price;+  int sell_quantity;++  template <typename Archive>+  void serialize(Archive& ar, const unsigned int version)+  {+    ar & code;+    ar & name;+    ar & open_price;+    ar & high_price;+    ar & low_price;+    ar & last_price;+    ar & buy_price;+    ar & buy_quantity;+    ar & sell_price;+    ar & sell_quantity;+  }+};++} // namespace s11n_example++#endif // SERIALIZATION_STOCK_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/services/basic_logger.hpp view
@@ -0,0 +1,77 @@+//+// basic_logger.hpp+// ~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef SERVICES_BASIC_LOGGER_HPP+#define SERVICES_BASIC_LOGGER_HPP++#include <asio.hpp>+#include <boost/noncopyable.hpp>+#include <string>++namespace services {++/// Class to provide simple logging functionality. Use the services::logger+/// typedef.+template <typename Service>+class basic_logger+  : private boost::noncopyable+{+public:+  /// The type of the service that will be used to provide timer operations.+  typedef Service service_type;++  /// The native implementation type of the timer.+  typedef typename service_type::impl_type impl_type;++  /// Constructor.+  /**+   * This constructor creates a logger.+   *+   * @param context The execution context used to locate the logger service.+   *+   * @param identifier An identifier for this logger.+   */+  explicit basic_logger(asio::execution_context& context,+      const std::string& identifier)+    : service_(asio::use_service<Service>(context)),+      impl_(service_.null())+  {+    service_.create(impl_, identifier);+  }++  /// Destructor.+  ~basic_logger()+  {+    service_.destroy(impl_);+  }++  /// Set the output file for all logger instances.+  void use_file(const std::string& file)+  {+    service_.use_file(impl_, file);+  }++  /// Log a message.+  void log(const std::string& message)+  {+    service_.log(impl_, message);+  }++private:+  /// The backend service implementation.+  service_type& service_;++  /// The underlying native implementation.+  impl_type impl_;+};++} // namespace services++#endif // SERVICES_BASIC_LOGGER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/services/logger.hpp view
@@ -0,0 +1,24 @@+//+// logger.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef SERVICES_LOGGER_HPP+#define SERVICES_LOGGER_HPP++#include "basic_logger.hpp"+#include "logger_service.hpp"++namespace services {++/// Typedef for typical logger usage.+typedef basic_logger<logger_service> logger;++} // namespace services++#endif // SERVICES_LOGGER_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/services/logger_service.hpp view
@@ -0,0 +1,145 @@+//+// logger_service.hpp+// ~~~~~~~~~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef SERVICES_LOGGER_SERVICE_HPP+#define SERVICES_LOGGER_SERVICE_HPP++#include <asio.hpp>+#include <boost/bind/bind.hpp>+#include <boost/date_time/posix_time/posix_time.hpp>+#include <boost/noncopyable.hpp>+#include <boost/scoped_ptr.hpp>+#include <fstream>+#include <sstream>+#include <string>++namespace services {++/// Service implementation for the logger.+class logger_service+  : public asio::execution_context::service+{+public:+  /// The type used to identify this service in the execution context.+  typedef logger_service key_type;++  /// The backend implementation of a logger.+  struct logger_impl+  {+    explicit logger_impl(const std::string& ident) : identifier(ident) {}+    std::string identifier;+  };++  /// The type for an implementation of the logger.+  typedef logger_impl* impl_type;++  /// Constructor creates a thread to run a private io_context.+  logger_service(asio::execution_context& context)+    : asio::execution_context::service(context),+      work_io_context_(),+      work_(asio::make_work_guard(work_io_context_)),+      work_thread_(new asio::thread(+            boost::bind(&asio::io_context::run, &work_io_context_)))+  {+  }++  /// Destructor shuts down the private io_context.+  ~logger_service()+  {+    /// Indicate that we have finished with the private io_context. Its+    /// io_context::run() function will exit once all other work has completed.+    work_.reset();+    if (work_thread_)+      work_thread_->join();+  }++  /// Destroy all user-defined handler objects owned by the service.+  void shutdown()+  {+  }++  /// Return a null logger implementation.+  impl_type null() const+  {+    return 0;+  }++  /// Create a new logger implementation.+  void create(impl_type& impl, const std::string& identifier)+  {+    impl = new logger_impl(identifier);+  }++  /// Destroy a logger implementation.+  void destroy(impl_type& impl)+  {+    delete impl;+    impl = null();+  }++  /// Set the output file for the logger. The current implementation sets the+  /// output file for all logger instances, and so the impl parameter is not+  /// actually needed. It is retained here to illustrate how service functions+  /// are typically defined.+  void use_file(impl_type& /*impl*/, const std::string& file)+  {+    // Pass the work of opening the file to the background thread.+    asio::post(work_io_context_, boost::bind(+          &logger_service::use_file_impl, this, file));+  }++  /// Log a message.+  void log(impl_type& impl, const std::string& message)+  {+    // Format the text to be logged.+    std::ostringstream os;+    os << impl->identifier << ": " << message;++    // Pass the work of writing to the file to the background thread.+    asio::post(work_io_context_, boost::bind(+          &logger_service::log_impl, this, os.str()));+  }++private:+  /// Helper function used to open the output file from within the private+  /// io_context's thread.+  void use_file_impl(const std::string& file)+  {+    ofstream_.close();+    ofstream_.clear();+    ofstream_.open(file.c_str());+  }++  /// Helper function used to log a message from within the private io_context's+  /// thread.+  void log_impl(const std::string& text)+  {+    ofstream_ << text << std::endl;+  }++  /// Private io_context used for performing logging operations.+  asio::io_context work_io_context_;++  /// Work for the private io_context to perform. If we do not give the+  /// io_context some work to do then the io_context::run() function will exit+  /// immediately.+  asio::executor_work_guard<+      asio::io_context::executor_type> work_;++  /// Thread used for running the work io_context's run loop.+  boost::scoped_ptr<asio::thread> work_thread_;++  /// The file to which log messages will be written.+  std::ofstream ofstream_;+};++} // namespace services++#endif // SERVICES_LOGGER_SERVICE_HPP
+ link/modules/asio-standalone/asio/src/examples/cpp03/socks4/socks4.hpp view
@@ -0,0 +1,144 @@+//+// socks4.hpp+// ~~~~~~~~~~+//+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)+//++#ifndef SOCKS4_HPP+#define SOCKS4_HPP++#include <string>+#include <asio.hpp>+#include <boost/array.hpp>++namespace socks4 {++const unsigned char version = 0x04;++class request+{+public:+  enum command_type+  {+    connect = 0x01,+    bind = 0x02+  };++  request(command_type cmd, const asio::ip::tcp::endpoint& endpoint,+      const std::string& user_id)+    : version_(version),+      command_(cmd),+      user_id_(user_id),+      null_byte_(0)+  {+    // Only IPv4 is supported by the SOCKS 4 protocol.+    if (endpoint.protocol() != asio::ip::tcp::v4())+    {+      throw asio::system_error(+          asio::error::address_family_not_supported);+    }++    // Convert port number to network byte order.+    unsigned short port = endpoint.port();+    port_high_byte_ = (port >> 8) & 0xff;+    port_low_byte_ = port & 0xff;++    // Save IP address in network byte order.+    address_ = endpoint.address().to_v4().to_bytes();+  }++  boost::array<asio::const_buffer, 7> buffers() const+  {+    boost::array<asio::const_buffer, 7> bufs =+    {+      {+        asio::buffer(&version_, 1),+        asio::buffer(&command_, 1),+        asio::buffer(&port_high_byte_, 1),+        asio::buffer(&port_low_byte_, 1),+        asio::buffer(address_),+        asio::buffer(user_id_),+        asio::buffer(&null_byte_, 1)+      }+    };+    return bufs;+  }++private:+  unsigned char version_;+  unsigned char command_;+  unsigned char port_high_byte_;+  unsigned char port_low_byte_;+  asio::ip::address_v4::bytes_type address_;+  std::string user_id_;+  unsigned char null_byte_;+};++class reply+{+public:+  enum status_type+  {+    request_granted = 0x5a,+    request_failed = 0x5b,+    request_failed_no_identd = 0x5c,+    request_failed_bad_user_id = 0x5d+  };++  reply()+    : null_byte_(0),+      status_()+  {+  }++  boost::array<asio::mutable_buffer, 5> buffers()+  {+    boost::array<asio::mutable_buffer, 5> bufs =+    {+      {+        asio::buffer(&null_byte_, 1),+        asio::buffer(&status_, 1),+        asio::buffer(&port_high_byte_, 1),+        asio::buffer(&port_low_byte_, 1),+        asio::buffer(address_)+      }+    };+    return bufs;+  }++  bool success() const+  {+    return null_byte_ == 0 && status_ == request_granted;+  }++  unsigned char status() const+  {+    return status_;+  }++  asio::ip::tcp::endpoint endpoint() const+  {+    unsigned short port = port_high_byte_;+    port = (port << 8) & 0xff00;+    port = port | port_low_byte_;++    asio::ip::address_v4 address(address_);++    return asio::ip::tcp::endpoint(address, port);+  }++private:+  unsigned char null_byte_;+  unsigned char status_;+  unsigned char port_high_byte_;+  unsigned char port_low_byte_;+  asio::ip::address_v4::bytes_type address_;+};++} // namespace socks4++#endif // SOCKS4_HPP
link/modules/asio-standalone/asio/src/examples/cpp11/chat/chat_message.hpp view
@@ -2,7 +2,7 @@ // chat_message.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -79,8 +79,7 @@   void encode_header()   {     char header[header_length + 1] = "";-    std::snprintf(header, header_length + 1,-        "%4d", static_cast<int>(body_length_));+    std::sprintf(header, "%4d", static_cast<int>(body_length_));     std::memcpy(data_, header, header_length);   } 
link/modules/asio-standalone/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp view
@@ -2,7 +2,7 @@ // custom_tracking.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -187,7 +187,7 @@    // Record a reactor-based operation that is associated with a handler.   static void reactor_operation(const tracked_handler& h,-      const char* op_name, const std::error_code& ec)+      const char* op_name, const asio::error_code& ec)   {     std::printf(         "Performed operation %s.%s for native_handle = %" PRIuMAX@@ -197,7 +197,7 @@    // Record a reactor-based operation that is associated with a handler.   static void reactor_operation(const tracked_handler& h,-      const char* op_name, const std::error_code& ec,+      const char* op_name, const asio::error_code& ec,       std::size_t bytes_transferred)   {     std::printf(
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/connection.hpp view
@@ -2,7 +2,7 @@ // connection.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -11,9 +11,9 @@ #ifndef HTTP_CONNECTION_HPP #define HTTP_CONNECTION_HPP -#include <asio.hpp> #include <array> #include <memory>+#include <asio.hpp> #include "reply.hpp" #include "request.hpp" #include "request_handler.hpp"
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/connection_manager.hpp view
@@ -2,7 +2,7 @@ // connection_manager.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/header.hpp view
@@ -2,7 +2,7 @@ // header.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/mime_types.hpp view
@@ -2,7 +2,7 @@ // mime_types.hpp // ~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/reply.hpp view
@@ -2,7 +2,7 @@ // reply.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request.hpp view
@@ -2,7 +2,7 @@ // request.hpp // ~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request_handler.hpp view
@@ -2,7 +2,7 @@ // request_handler.hpp // ~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/request_parser.hpp view
@@ -2,7 +2,7 @@ // request_parser.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp11/http/server/server.hpp view
@@ -2,7 +2,7 @@ // server.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/connection.hpp
@@ -1,71 +0,0 @@-//-// connection.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER2_CONNECTION_HPP-#define HTTP_SERVER2_CONNECTION_HPP--#include <asio.hpp>-#include <array>-#include <memory>-#include "reply.hpp"-#include "request.hpp"-#include "request_handler.hpp"-#include "request_parser.hpp"--namespace http {-namespace server2 {--/// Represents a single connection from a client.-class connection-  : public std::enable_shared_from_this<connection>-{-public:-  connection(const connection&) = delete;-  connection& operator=(const connection&) = delete;--  /// Construct a connection with the given socket.-  explicit connection(asio::ip::tcp::socket socket,-      request_handler& handler);--  /// Start the first asynchronous operation for the connection.-  void start();--private:-  /// Perform an asynchronous read operation.-  void do_read();--  /// Perform an asynchronous write operation.-  void do_write();--  /// Socket for the connection.-  asio::ip::tcp::socket socket_;--  /// The handler used to process the incoming request.-  request_handler& request_handler_;--  /// Buffer for incoming data.-  std::array<char, 8192> buffer_;--  /// The incoming request.-  request request_;--  /// The parser for the incoming request.-  request_parser request_parser_;--  /// The reply to be sent back to the client.-  reply reply_;-};--typedef std::shared_ptr<connection> connection_ptr;--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_CONNECTION_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/header.hpp
@@ -1,28 +0,0 @@-//-// header.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER2_HEADER_HPP-#define HTTP_SERVER2_HEADER_HPP--#include <string>--namespace http {-namespace server2 {--struct header-{-  std::string name;-  std::string value;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/io_context_pool.hpp
@@ -1,59 +0,0 @@-//-// io_context_pool.hpp-// ~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER2_IO_SERVICE_POOL_HPP-#define HTTP_SERVER2_IO_SERVICE_POOL_HPP--#include <asio.hpp>-#include <list>-#include <memory>-#include <vector>--namespace http {-namespace server2 {--/// A pool of io_context objects.-class io_context_pool-{-public:-  /// Construct the io_context pool.-  explicit io_context_pool(std::size_t pool_size);--  /// Run all io_context objects in the pool.-  void run();--  /// Stop all io_context objects in the pool.-  void stop();--  /// Get an io_context to use.-  asio::io_context& get_io_context();--private:-  io_context_pool(const io_context_pool&) = delete;-  io_context_pool& operator=(const io_context_pool&) = delete;--  typedef std::shared_ptr<asio::io_context> io_context_ptr;-  typedef asio::executor_work_guard<-    asio::io_context::executor_type> io_context_work;--  /// The pool of io_contexts.-  std::vector<io_context_ptr> io_contexts_;--  /// The work that keeps the io_contexts running.-  std::list<io_context_work> work_;--  /// The next io_context to use for a connection.-  std::size_t next_io_context_;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_IO_SERVICE_POOL_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/mime_types.hpp
@@ -1,27 +0,0 @@-//-// mime_types.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER2_MIME_TYPES_HPP-#define HTTP_SERVER2_MIME_TYPES_HPP--#include <string>--namespace http {-namespace server2 {-namespace mime_types {--/// Convert a file extension into a MIME type.-std::string extension_to_type(const std::string& extension);--} // namespace mime_types-} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_MIME_TYPES_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/reply.hpp
@@ -1,64 +0,0 @@-//-// reply.hpp-// ~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER2_REPLY_HPP-#define HTTP_SERVER2_REPLY_HPP--#include <string>-#include <vector>-#include <asio.hpp>-#include "header.hpp"--namespace http {-namespace server2 {--/// A reply to be sent to a client.-struct reply-{-  /// The status of the reply.-  enum status_type-  {-    ok = 200,-    created = 201,-    accepted = 202,-    no_content = 204,-    multiple_choices = 300,-    moved_permanently = 301,-    moved_temporarily = 302,-    not_modified = 304,-    bad_request = 400,-    unauthorized = 401,-    forbidden = 403,-    not_found = 404,-    internal_server_error = 500,-    not_implemented = 501,-    bad_gateway = 502,-    service_unavailable = 503-  } status;--  /// The headers to be included in the reply.-  std::vector<header> headers;--  /// The content to be sent in the reply.-  std::string content;--  /// Convert the reply into a vector of buffers. The buffers do not own the-  /// underlying memory blocks, therefore the reply object must remain valid and-  /// not be changed until the write operation has completed.-  std::vector<asio::const_buffer> to_buffers();--  /// Get a stock reply.-  static reply stock_reply(status_type status);-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_REPLY_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request.hpp
@@ -1,34 +0,0 @@-//-// request.hpp-// ~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER2_REQUEST_HPP-#define HTTP_SERVER2_REQUEST_HPP--#include <string>-#include <vector>-#include "header.hpp"--namespace http {-namespace server2 {--/// A request received from a client.-struct request-{-  std::string method;-  std::string uri;-  int http_version_major;-  int http_version_minor;-  std::vector<header> headers;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_REQUEST_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request_handler.hpp
@@ -1,47 +0,0 @@-//-// request_handler.hpp-// ~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER2_REQUEST_HANDLER_HPP-#define HTTP_SERVER2_REQUEST_HANDLER_HPP--#include <string>--namespace http {-namespace server2 {--struct reply;-struct request;--/// The common handler for all incoming requests.-class request_handler-{-public:-  request_handler(const request_handler&) = delete;-  request_handler& operator=(const request_handler&) = delete;--  /// Construct with a directory containing files to be served.-  explicit request_handler(const std::string& doc_root);--  /// Handle a request and produce a reply.-  void handle_request(const request& req, reply& rep);--private:-  /// The directory containing the files to be served.-  std::string doc_root_;--  /// Perform URL-decoding on a string. Returns false if the encoding was-  /// invalid.-  static bool url_decode(const std::string& in, std::string& out);-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_REQUEST_HANDLER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/request_parser.hpp
@@ -1,96 +0,0 @@-//-// request_parser.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER2_REQUEST_PARSER_HPP-#define HTTP_SERVER2_REQUEST_PARSER_HPP--#include <tuple>--namespace http {-namespace server2 {--struct request;--/// Parser for incoming requests.-class request_parser-{-public:-  /// Construct ready to parse the request method.-  request_parser();--  /// Reset to initial parser state.-  void reset();--  /// Result of parse.-  enum result_type { good, bad, indeterminate };--  /// Parse some data. The enum return value is good when a complete request has-  /// been parsed, bad if the data is invalid, indeterminate when more data is-  /// required. The InputIterator return value indicates how much of the input-  /// has been consumed.-  template <typename InputIterator>-  std::tuple<result_type, InputIterator> parse(request& req,-      InputIterator begin, InputIterator end)-  {-    while (begin != end)-    {-      result_type result = consume(req, *begin++);-      if (result == good || result == bad)-        return std::make_tuple(result, begin);-    }-    return std::make_tuple(indeterminate, begin);-  }--private:-  /// Handle the next character of input.-  result_type consume(request& req, char input);--  /// Check if a byte is an HTTP character.-  static bool is_char(int c);--  /// Check if a byte is an HTTP control character.-  static bool is_ctl(int c);--  /// Check if a byte is defined as an HTTP tspecial character.-  static bool is_tspecial(int c);--  /// Check if a byte is a digit.-  static bool is_digit(int c);--  /// The current state of the parser.-  enum state-  {-    method_start,-    method,-    uri,-    http_version_h,-    http_version_t_1,-    http_version_t_2,-    http_version_p,-    http_version_slash,-    http_version_major_start,-    http_version_major,-    http_version_minor_start,-    http_version_minor,-    expecting_newline_1,-    header_line_start,-    header_lws,-    header_name,-    space_before_header_value,-    header_value,-    expecting_newline_2,-    expecting_newline_3-  } state_;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_REQUEST_PARSER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server2/server.hpp
@@ -1,60 +0,0 @@-//-// server.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER2_SERVER_HPP-#define HTTP_SERVER2_SERVER_HPP--#include <asio.hpp>-#include <string>-#include "io_context_pool.hpp"-#include "request_handler.hpp"--namespace http {-namespace server2 {--/// The top-level class of the HTTP server.-class server-{-public:-  server(const server&) = delete;-  server& operator=(const server&) = delete;--  /// Construct the server to listen on the specified TCP address and port, and-  /// serve up files from the given directory.-  explicit server(const std::string& address, const std::string& port,-      const std::string& doc_root, std::size_t io_context_pool_size);--  /// Run the server's io_context loop.-  void run();--private:-  /// Perform an asynchronous accept operation.-  void do_accept();--  /// Wait for a request to stop the server.-  void do_await_stop();--  /// The pool of io_context objects used to perform asynchronous operations.-  io_context_pool io_context_pool_;--  /// The signal_set is used to register for process termination notifications.-  asio::signal_set signals_;--  /// Acceptor used to listen for incoming connections.-  asio::ip::tcp::acceptor acceptor_;--  /// The handler for all incoming requests.-  request_handler request_handler_;-};--} // namespace server2-} // namespace http--#endif // HTTP_SERVER2_SERVER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/connection.hpp
@@ -1,71 +0,0 @@-//-// connection.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER3_CONNECTION_HPP-#define HTTP_SERVER3_CONNECTION_HPP--#include <asio.hpp>-#include <array>-#include <memory>-#include "reply.hpp"-#include "request.hpp"-#include "request_handler.hpp"-#include "request_parser.hpp"--namespace http {-namespace server3 {--/// Represents a single connection from a client.-class connection-  : public std::enable_shared_from_this<connection>-{-public:-  connection(const connection&) = delete;-  connection& operator=(const connection&) = delete;--  /// Construct a connection with the given socket.-  explicit connection(asio::ip::tcp::socket socket,-      request_handler& handler);--  /// Start the first asynchronous operation for the connection.-  void start();--private:-  /// Perform an asynchronous read operation.-  void do_read();--  /// Perform an asynchronous write operation.-  void do_write();--  /// Socket for the connection.-  asio::ip::tcp::socket socket_;--  /// The handler used to process the incoming request.-  request_handler& request_handler_;--  /// Buffer for incoming data.-  std::array<char, 8192> buffer_;--  /// The incoming request.-  request request_;--  /// The parser for the incoming request.-  request_parser request_parser_;--  /// The reply to be sent back to the client.-  reply reply_;-};--typedef std::shared_ptr<connection> connection_ptr;--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_CONNECTION_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/header.hpp
@@ -1,28 +0,0 @@-//-// header.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER3_HEADER_HPP-#define HTTP_SERVER3_HEADER_HPP--#include <string>--namespace http {-namespace server3 {--struct header-{-  std::string name;-  std::string value;-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/mime_types.hpp
@@ -1,27 +0,0 @@-//-// mime_types.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER3_MIME_TYPES_HPP-#define HTTP_SERVER3_MIME_TYPES_HPP--#include <string>--namespace http {-namespace server3 {-namespace mime_types {--/// Convert a file extension into a MIME type.-std::string extension_to_type(const std::string& extension);--} // namespace mime_types-} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_MIME_TYPES_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/reply.hpp
@@ -1,64 +0,0 @@-//-// reply.hpp-// ~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER3_REPLY_HPP-#define HTTP_SERVER3_REPLY_HPP--#include <string>-#include <vector>-#include <asio.hpp>-#include "header.hpp"--namespace http {-namespace server3 {--/// A reply to be sent to a client.-struct reply-{-  /// The status of the reply.-  enum status_type-  {-    ok = 200,-    created = 201,-    accepted = 202,-    no_content = 204,-    multiple_choices = 300,-    moved_permanently = 301,-    moved_temporarily = 302,-    not_modified = 304,-    bad_request = 400,-    unauthorized = 401,-    forbidden = 403,-    not_found = 404,-    internal_server_error = 500,-    not_implemented = 501,-    bad_gateway = 502,-    service_unavailable = 503-  } status;--  /// The headers to be included in the reply.-  std::vector<header> headers;--  /// The content to be sent in the reply.-  std::string content;--  /// Convert the reply into a vector of buffers. The buffers do not own the-  /// underlying memory blocks, therefore the reply object must remain valid and-  /// not be changed until the write operation has completed.-  std::vector<asio::const_buffer> to_buffers();--  /// Get a stock reply.-  static reply stock_reply(status_type status);-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_REPLY_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request.hpp
@@ -1,34 +0,0 @@-//-// request.hpp-// ~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER3_REQUEST_HPP-#define HTTP_SERVER3_REQUEST_HPP--#include <string>-#include <vector>-#include "header.hpp"--namespace http {-namespace server3 {--/// A request received from a client.-struct request-{-  std::string method;-  std::string uri;-  int http_version_major;-  int http_version_minor;-  std::vector<header> headers;-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_REQUEST_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request_handler.hpp
@@ -1,47 +0,0 @@-//-// request_handler.hpp-// ~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER3_REQUEST_HANDLER_HPP-#define HTTP_SERVER3_REQUEST_HANDLER_HPP--#include <string>--namespace http {-namespace server3 {--struct reply;-struct request;--/// The common handler for all incoming requests.-class request_handler-{-public:-  request_handler(const request_handler&) = delete;-  request_handler& operator=(const request_handler&) = delete;--  /// Construct with a directory containing files to be served.-  explicit request_handler(const std::string& doc_root);--  /// Handle a request and produce a reply.-  void handle_request(const request& req, reply& rep);--private:-  /// The directory containing the files to be served.-  std::string doc_root_;--  /// Perform URL-decoding on a string. Returns false if the encoding was-  /// invalid.-  static bool url_decode(const std::string& in, std::string& out);-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_REQUEST_HANDLER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/request_parser.hpp
@@ -1,96 +0,0 @@-//-// request_parser.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER3_REQUEST_PARSER_HPP-#define HTTP_SERVER3_REQUEST_PARSER_HPP--#include <tuple>--namespace http {-namespace server3 {--struct request;--/// Parser for incoming requests.-class request_parser-{-public:-  /// Construct ready to parse the request method.-  request_parser();--  /// Reset to initial parser state.-  void reset();--  /// Result of parse.-  enum result_type { good, bad, indeterminate };--  /// Parse some data. The enum return value is good when a complete request has-  /// been parsed, bad if the data is invalid, indeterminate when more data is-  /// required. The InputIterator return value indicates how much of the input-  /// has been consumed.-  template <typename InputIterator>-  std::tuple<result_type, InputIterator> parse(request& req,-      InputIterator begin, InputIterator end)-  {-    while (begin != end)-    {-      result_type result = consume(req, *begin++);-      if (result == good || result == bad)-        return std::make_tuple(result, begin);-    }-    return std::make_tuple(indeterminate, begin);-  }--private:-  /// Handle the next character of input.-  result_type consume(request& req, char input);--  /// Check if a byte is an HTTP character.-  static bool is_char(int c);--  /// Check if a byte is an HTTP control character.-  static bool is_ctl(int c);--  /// Check if a byte is defined as an HTTP tspecial character.-  static bool is_tspecial(int c);--  /// Check if a byte is a digit.-  static bool is_digit(int c);--  /// The current state of the parser.-  enum state-  {-    method_start,-    method,-    uri,-    http_version_h,-    http_version_t_1,-    http_version_t_2,-    http_version_p,-    http_version_slash,-    http_version_major_start,-    http_version_major,-    http_version_minor_start,-    http_version_minor,-    expecting_newline_1,-    header_line_start,-    header_lws,-    header_name,-    space_before_header_value,-    header_value,-    expecting_newline_2,-    expecting_newline_3-  } state_;-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_REQUEST_PARSER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server3/server.hpp
@@ -1,62 +0,0 @@-//-// server.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER3_SERVER_HPP-#define HTTP_SERVER3_SERVER_HPP--#include <asio.hpp>-#include <string>-#include "request_handler.hpp"--namespace http {-namespace server3 {--/// The top-level class of the HTTP server.-class server-{-public:-  server(const server&) = delete;-  server& operator=(const server&) = delete;--  /// Construct the server to listen on the specified TCP address and port, and-  /// serve up files from the given directory.-  explicit server(const std::string& address, const std::string& port,-      const std::string& doc_root, std::size_t thread_pool_size);--  /// Run the server's io_context loop.-  void run();--private:-  /// Perform an asynchronous accept operation.-  void do_accept();--  /// Wait for a request to stop the server.-  void do_await_stop();--  /// The number of threads that will call io_context::run().-  std::size_t thread_pool_size_;--  /// The io_context used to perform asynchronous operations.-  asio::io_context io_context_;--  /// The signal_set is used to register for process termination notifications.-  asio::signal_set signals_;--  /// Acceptor used to listen for incoming connections.-  asio::ip::tcp::acceptor acceptor_;--  /// The handler for all incoming requests.-  request_handler request_handler_;-};--} // namespace server3-} // namespace http--#endif // HTTP_SERVER3_SERVER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/file_handler.hpp
@@ -1,44 +0,0 @@-//-// file_handler.hpp-// ~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER4_FILE_HANDLER_HPP-#define HTTP_SERVER4_FILE_HANDLER_HPP--#include <string>--namespace http {-namespace server4 {--struct reply;-struct request;--/// The common handler for all incoming requests.-class file_handler-{-public:-  /// Construct with a directory containing files to be served.-  explicit file_handler(const std::string& doc_root);--  /// Handle a request and produce a reply.-  void operator()(const request& req, reply& rep);--private:-  /// The directory containing the files to be served.-  std::string doc_root_;--  /// Perform URL-decoding on a string. Returns false if the encoding was-  /// invalid.-  static bool url_decode(const std::string& in, std::string& out);-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_FILE_HANDLER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/header.hpp
@@ -1,28 +0,0 @@-//-// header.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER4_HEADER_HPP-#define HTTP_SERVER4_HEADER_HPP--#include <string>--namespace http {-namespace server4 {--struct header-{-  std::string name;-  std::string value;-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/mime_types.hpp
@@ -1,27 +0,0 @@-//-// mime_types.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER4_MIME_TYPES_HPP-#define HTTP_SERVER4_MIME_TYPES_HPP--#include <string>--namespace http {-namespace server4 {-namespace mime_types {--/// Convert a file extension into a MIME type.-std::string extension_to_type(const std::string& extension);--} // namespace mime_types-} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_MIME_TYPES_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/reply.hpp
@@ -1,64 +0,0 @@-//-// reply.hpp-// ~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER4_REPLY_HPP-#define HTTP_SERVER4_REPLY_HPP--#include <string>-#include <vector>-#include <asio.hpp>-#include "header.hpp"--namespace http {-namespace server4 {--/// A reply to be sent to a client.-struct reply-{-  /// The status of the reply.-  enum status_type-  {-    ok = 200,-    created = 201,-    accepted = 202,-    no_content = 204,-    multiple_choices = 300,-    moved_permanently = 301,-    moved_temporarily = 302,-    not_modified = 304,-    bad_request = 400,-    unauthorized = 401,-    forbidden = 403,-    not_found = 404,-    internal_server_error = 500,-    not_implemented = 501,-    bad_gateway = 502,-    service_unavailable = 503-  } status;--  /// The headers to be included in the reply.-  std::vector<header> headers;--  /// The content to be sent in the reply.-  std::string content;--  /// Convert the reply into a vector of buffers. The buffers do not own the-  /// underlying memory blocks, therefore the reply object must remain valid and-  /// not be changed until the write operation has completed.-  std::vector<asio::const_buffer> to_buffers();--  /// Get a stock reply.-  static reply stock_reply(status_type status);-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_REPLY_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request.hpp
@@ -1,34 +0,0 @@-//-// request.hpp-// ~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER4_REQUEST_HPP-#define HTTP_SERVER4_REQUEST_HPP--#include <string>-#include <vector>-#include "header.hpp"--namespace http {-namespace server4 {--/// A request received from a client.-struct request-{-  std::string method;-  std::string uri;-  int http_version_major;-  int http_version_minor;-  std::vector<header> headers;-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_REQUEST_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request_handler.hpp
@@ -1,47 +0,0 @@-//-// request_handler.hpp-// ~~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER4_REQUEST_HANDLER_HPP-#define HTTP_SERVER4_REQUEST_HANDLER_HPP--#include <string>--namespace http {-namespace server4 {--struct reply;-struct request;--/// The common handler for all incoming requests.-class request_handler-{-public:-  request_handler(const request_handler&) = delete;-  request_handler& operator=(const request_handler&) = delete;--  /// Construct with a directory containing files to be served.-  explicit request_handler(const std::string& doc_root);--  /// Handle a request and produce a reply.-  void handle_request(const request& req, reply& rep);--private:-  /// The directory containing the files to be served.-  std::string doc_root_;--  /// Perform URL-decoding on a string. Returns false if the encoding was-  /// invalid.-  static bool url_decode(const std::string& in, std::string& out);-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_REQUEST_HANDLER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/request_parser.hpp
@@ -1,96 +0,0 @@-//-// request_parser.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER4_REQUEST_PARSER_HPP-#define HTTP_SERVER4_REQUEST_PARSER_HPP--#include <tuple>--namespace http {-namespace server4 {--struct request;--/// Parser for incoming requests.-class request_parser-{-public:-  /// Construct ready to parse the request method.-  request_parser();--  /// Reset to initial parser state.-  void reset();--  /// Result of parse.-  enum result_type { good, bad, indeterminate };--  /// Parse some data. The enum return value is good when a complete request has-  /// been parsed, bad if the data is invalid, indeterminate when more data is-  /// required. The InputIterator return value indicates how much of the input-  /// has been consumed.-  template <typename InputIterator>-  std::tuple<result_type, InputIterator> parse(request& req,-      InputIterator begin, InputIterator end)-  {-    while (begin != end)-    {-      result_type result = consume(req, *begin++);-      if (result == good || result == bad)-        return std::make_tuple(result, begin);-    }-    return std::make_tuple(indeterminate, begin);-  }--private:-  /// Handle the next character of input.-  result_type consume(request& req, char input);--  /// Check if a byte is an HTTP character.-  static bool is_char(int c);--  /// Check if a byte is an HTTP control character.-  static bool is_ctl(int c);--  /// Check if a byte is defined as an HTTP tspecial character.-  static bool is_tspecial(int c);--  /// Check if a byte is a digit.-  static bool is_digit(int c);--  /// The current state of the parser.-  enum state-  {-    method_start,-    method,-    uri,-    http_version_h,-    http_version_t_1,-    http_version_t_2,-    http_version_p,-    http_version_slash,-    http_version_major_start,-    http_version_major,-    http_version_minor_start,-    http_version_minor,-    expecting_newline_1,-    header_line_start,-    header_lws,-    header_name,-    space_before_header_value,-    header_value,-    expecting_newline_2,-    expecting_newline_3-  } state_;-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_REQUEST_PARSER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/http/server4/server.hpp
@@ -1,73 +0,0 @@-//-// server.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef HTTP_SERVER4_SERVER_HPP-#define HTTP_SERVER4_SERVER_HPP--#include <asio.hpp>-#include <array>-#include <functional>-#include <memory>-#include <string>-#include "request_parser.hpp"--namespace http {-namespace server4 {--struct request;-struct reply;--/// The top-level coroutine of the HTTP server.-class server : asio::coroutine-{-public:-  /// Construct the server to listen on the specified TCP address and port, and-  /// serve up files from the given directory.-  explicit server(asio::io_context& io_context,-      const std::string& address, const std::string& port,-      std::function<void(const request&, reply&)> request_handler);--  /// Perform work associated with the server.-  void operator()(-      std::error_code ec = std::error_code(),-      std::size_t length = 0);--private:-  typedef asio::ip::tcp tcp;--  /// The user-supplied handler for all incoming requests.-  std::function<void(const request&, reply&)> request_handler_;--  /// Acceptor used to listen for incoming connections.-  std::shared_ptr<tcp::acceptor> acceptor_;--  /// The current connection from a client.-  std::shared_ptr<tcp::socket> socket_;--  /// Buffer for incoming data.-  std::shared_ptr<std::array<char, 8192>> buffer_;--  /// The incoming request.-  std::shared_ptr<request> request_;--  /// Whether the request is valid or not.-  request_parser::result_type parse_result_;--  /// The parser for the incoming request.-  request_parser request_parser_;--  /// The reply to be sent back to the client.-  std::shared_ptr<reply> reply_;-};--} // namespace server4-} // namespace http--#endif // HTTP_SERVER4_SERVER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/icmp/icmp_header.hpp
@@ -1,94 +0,0 @@-//-// icmp_header.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef ICMP_HEADER_HPP-#define ICMP_HEADER_HPP--#include <istream>-#include <ostream>-#include <algorithm>--// ICMP header for both IPv4 and IPv6.-//-// The wire format of an ICMP header is:-//-// 0               8               16                             31-// +---------------+---------------+------------------------------+      ----// |               |               |                              |       ^-// |     type      |     code      |          checksum            |       |-// |               |               |                              |       |-// +---------------+---------------+------------------------------+    8 bytes-// |                               |                              |       |-// |          identifier           |       sequence number        |       |-// |                               |                              |       v-// +-------------------------------+------------------------------+      -----class icmp_header-{-public:-  enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4,-    redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12,-    timestamp_request = 13, timestamp_reply = 14, info_request = 15,-    info_reply = 16, address_request = 17, address_reply = 18 };--  icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }--  unsigned char type() const { return rep_[0]; }-  unsigned char code() const { return rep_[1]; }-  unsigned short checksum() const { return decode(2, 3); }-  unsigned short identifier() const { return decode(4, 5); }-  unsigned short sequence_number() const { return decode(6, 7); }--  void type(unsigned char n) { rep_[0] = n; }-  void code(unsigned char n) { rep_[1] = n; }-  void checksum(unsigned short n) { encode(2, 3, n); }-  void identifier(unsigned short n) { encode(4, 5, n); }-  void sequence_number(unsigned short n) { encode(6, 7, n); }--  friend std::istream& operator>>(std::istream& is, icmp_header& header)-    { return is.read(reinterpret_cast<char*>(header.rep_), 8); }--  friend std::ostream& operator<<(std::ostream& os, const icmp_header& header)-    { return os.write(reinterpret_cast<const char*>(header.rep_), 8); }--private:-  unsigned short decode(int a, int b) const-    { return (rep_[a] << 8) + rep_[b]; }--  void encode(int a, int b, unsigned short n)-  {-    rep_[a] = static_cast<unsigned char>(n >> 8);-    rep_[b] = static_cast<unsigned char>(n & 0xFF);-  }--  unsigned char rep_[8];-};--template <typename Iterator>-void compute_checksum(icmp_header& header,-    Iterator body_begin, Iterator body_end)-{-  unsigned int sum = (header.type() << 8) + header.code()-    + header.identifier() + header.sequence_number();--  Iterator body_iter = body_begin;-  while (body_iter != body_end)-  {-    sum += (static_cast<unsigned char>(*body_iter++) << 8);-    if (body_iter != body_end)-      sum += static_cast<unsigned char>(*body_iter++);-  }--  sum = (sum >> 16) + (sum & 0xFFFF);-  sum += (sum >> 16);-  header.checksum(static_cast<unsigned short>(~sum));-}--#endif // ICMP_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/icmp/ipv4_header.hpp
@@ -1,102 +0,0 @@-//-// ipv4_header.hpp-// ~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef IPV4_HEADER_HPP-#define IPV4_HEADER_HPP--#include <algorithm>-#include <asio/ip/address_v4.hpp>--// Packet header for IPv4.-//-// The wire format of an IPv4 header is:-//-// 0               8               16                             31-// +-------+-------+---------------+------------------------------+      ----// |       |       |               |                              |       ^-// |version|header |    type of    |    total length in bytes     |       |-// |  (4)  | length|    service    |                              |       |-// +-------+-------+---------------+-+-+-+------------------------+       |-// |                               | | | |                        |       |-// |        identification         |0|D|M|    fragment offset     |       |-// |                               | |F|F|                        |       |-// +---------------+---------------+-+-+-+------------------------+       |-// |               |               |                              |       |-// | time to live  |   protocol    |       header checksum        |   20 bytes-// |               |               |                              |       |-// +---------------+---------------+------------------------------+       |-// |                                                              |       |-// |                      source IPv4 address                     |       |-// |                                                              |       |-// +--------------------------------------------------------------+       |-// |                                                              |       |-// |                   destination IPv4 address                   |       |-// |                                                              |       v-// +--------------------------------------------------------------+      ----// |                                                              |       ^-// |                                                              |       |-// /                        options (if any)                      /    0 - 40-// /                                                              /     bytes-// |                                                              |       |-// |                                                              |       v-// +--------------------------------------------------------------+      -----class ipv4_header-{-public:-  ipv4_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }--  unsigned char version() const { return (rep_[0] >> 4) & 0xF; }-  unsigned short header_length() const { return (rep_[0] & 0xF) * 4; }-  unsigned char type_of_service() const { return rep_[1]; }-  unsigned short total_length() const { return decode(2, 3); }-  unsigned short identification() const { return decode(4, 5); }-  bool dont_fragment() const { return (rep_[6] & 0x40) != 0; }-  bool more_fragments() const { return (rep_[6] & 0x20) != 0; }-  unsigned short fragment_offset() const { return decode(6, 7) & 0x1FFF; }-  unsigned int time_to_live() const { return rep_[8]; }-  unsigned char protocol() const { return rep_[9]; }-  unsigned short header_checksum() const { return decode(10, 11); }--  asio::ip::address_v4 source_address() const-  {-    asio::ip::address_v4::bytes_type bytes-      = { { rep_[12], rep_[13], rep_[14], rep_[15] } };-    return asio::ip::address_v4(bytes);-  }--  asio::ip::address_v4 destination_address() const-  {-    asio::ip::address_v4::bytes_type bytes-      = { { rep_[16], rep_[17], rep_[18], rep_[19] } };-    return asio::ip::address_v4(bytes);-  }--  friend std::istream& operator>>(std::istream& is, ipv4_header& header)-  {-    is.read(reinterpret_cast<char*>(header.rep_), 20);-    if (header.version() != 4)-      is.setstate(std::ios::failbit);-    std::streamsize options_length = header.header_length() - 20;-    if (options_length < 0 || options_length > 40)-      is.setstate(std::ios::failbit);-    else-      is.read(reinterpret_cast<char*>(header.rep_) + 20, options_length);-    return is;-  }--private:-  unsigned short decode(int a, int b) const-    { return (rep_[a] << 8) + rep_[b]; }--  unsigned char rep_[60];-};--#endif // IPV4_HEADER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/porthopper/protocol.hpp
@@ -1,156 +0,0 @@-//-// protocol.hpp-// ~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef PORTHOPPER_PROTOCOL_HPP-#define PORTHOPPER_PROTOCOL_HPP--#include <asio.hpp>-#include <array>-#include <cstring>-#include <iomanip>-#include <string>-#include <strstream>--// This request is sent by the client to the server over a TCP connection.-// The client uses it to perform three functions:-// - To request that data start being sent to a given port.-// - To request that data is no longer sent to a given port.-// - To change the target port to another.-class control_request-{-public:-  // Construct an empty request. Used when receiving.-  control_request()-  {-  }--  // Create a request to start sending data to a given port.-  static const control_request start(unsigned short port)-  {-    return control_request(0, port);-  }--  // Create a request to stop sending data to a given port.-  static const control_request stop(unsigned short port)-  {-    return control_request(port, 0);-  }--  // Create a request to change the port that data is sent to.-  static const control_request change(-      unsigned short old_port, unsigned short new_port)-  {-    return control_request(old_port, new_port);-  }--  // Get the old port. Returns 0 for start requests.-  unsigned short old_port() const-  {-    std::istrstream is(data_, encoded_port_size);-    unsigned short port = 0;-    is >> std::setw(encoded_port_size) >> std::hex >> port;-    return port;-  }--  // Get the new port. Returns 0 for stop requests.-  unsigned short new_port() const-  {-    std::istrstream is(data_ + encoded_port_size, encoded_port_size);-    unsigned short port = 0;-    is >> std::setw(encoded_port_size) >> std::hex >> port;-    return port;-  }--  // Obtain buffers for reading from or writing to a socket.-  std::array<asio::mutable_buffer, 1> to_buffers()-  {-    std::array<asio::mutable_buffer, 1> buffers-      = { { asio::buffer(data_) } };-    return buffers;-  }--private:-  // Construct with specified old and new ports.-  control_request(unsigned short old_port_number,-      unsigned short new_port_number)-  {-    std::ostrstream os(data_, control_request_size);-    os << std::setw(encoded_port_size) << std::hex << old_port_number;-    os << std::setw(encoded_port_size) << std::hex << new_port_number;-  }--  // The length in bytes of a control_request and its components.-  enum-  {-    encoded_port_size = 4, // 16-bit port in hex.-    control_request_size = encoded_port_size * 2-  };--  // The encoded request data.-  char data_[control_request_size];-};--// This frame is sent from the server to subscribed clients over UDP.-class frame-{-public:-  // The maximum allowable length of the payload.-  enum { payload_size = 32 };--  // Construct an empty frame. Used when receiving.-  frame()-  {-  }--  // Construct a frame with specified frame number and payload.-  frame(unsigned long frame_number, const std::string& payload_data)-  {-    std::ostrstream os(data_, frame_size);-    os << std::setw(encoded_number_size) << std::hex << frame_number;-    os << std::setw(payload_size)-      << std::setfill(' ') << payload_data.substr(0, payload_size);-  }--  // Get the frame number.-  unsigned long number() const-  {-    std::istrstream is(data_, encoded_number_size);-    unsigned long frame_number = 0;-    is >> std::setw(encoded_number_size) >> std::hex >> frame_number;-    return frame_number;-  }--  // Get the payload data.-  const std::string payload() const-  {-    return std::string(data_ + encoded_number_size, payload_size);-  }--  // Obtain buffers for reading from or writing to a socket.-  std::array<asio::mutable_buffer, 1> to_buffers()-  {-    std::array<asio::mutable_buffer, 1> buffers-      = { { asio::buffer(data_) } };-    return buffers;-  }--private:-  // The length in bytes of a frame and its components.-  enum-  {-    encoded_number_size = 8, // Frame number in hex.-    frame_size = encoded_number_size + payload_size-  };--  // The encoded frame data.-  char data_[frame_size];-};--#endif // PORTHOPPER_PROTOCOL_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/serialization/connection.hpp
@@ -1,184 +0,0 @@-//-// connection.hpp-// ~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef SERIALIZATION_CONNECTION_HPP-#define SERIALIZATION_CONNECTION_HPP--#include <asio.hpp>-#include <boost/archive/text_iarchive.hpp>-#include <boost/archive/text_oarchive.hpp>-#include <functional>-#include <iomanip>-#include <memory>-#include <string>-#include <sstream>-#include <tuple>-#include <vector>--namespace s11n_example {--/// The connection class provides serialization primitives on top of a socket.-/**- * Each message sent using this class consists of:- * @li An 8-byte header containing the length of the serialized data in- * hexadecimal.- * @li The serialized data.- */-class connection-{-public:-  /// Constructor.-  connection(const asio::any_io_executor& ex)-    : socket_(ex)-  {-  }--  /// Get the underlying socket. Used for making a connection or for accepting-  /// an incoming connection.-  asio::ip::tcp::socket& socket()-  {-    return socket_;-  }--  /// Asynchronously write a data structure to the socket.-  template <typename T, typename Handler>-  void async_write(const T& t, Handler handler)-  {-    // Serialize the data first so we know how large it is.-    std::ostringstream archive_stream;-    boost::archive::text_oarchive archive(archive_stream);-    archive << t;-    outbound_data_ = archive_stream.str();--    // Format the header.-    std::ostringstream header_stream;-    header_stream << std::setw(header_length)-      << std::hex << outbound_data_.size();-    if (!header_stream || header_stream.str().size() != header_length)-    {-      // Something went wrong, inform the caller.-      std::error_code error(asio::error::invalid_argument);-      asio::post(socket_.get_executor(), std::bind(handler, error));-      return;-    }-    outbound_header_ = header_stream.str();--    // Write the serialized data to the socket. We use "gather-write" to send-    // both the header and the data in a single write operation.-    std::vector<asio::const_buffer> buffers;-    buffers.push_back(asio::buffer(outbound_header_));-    buffers.push_back(asio::buffer(outbound_data_));-    asio::async_write(socket_, buffers, handler);-  }--  /// Asynchronously read a data structure from the socket.-  template <typename T, typename Handler>-  void async_read(T& t, Handler handler)-  {-    // Issue a read operation to read exactly the number of bytes in a header.-    void (connection::*f)(const std::error_code&, T&, std::tuple<Handler>)-      = &connection::handle_read_header<T, Handler>;-    asio::async_read(socket_, asio::buffer(inbound_header_),-        std::bind(f,-          this, asio::placeholders::error, std::ref(t),-          std::make_tuple(handler)));-  }--  /// Handle a completed read of a message header.-  template <typename T, typename Handler>-  void handle_read_header(const std::error_code& e,-      T& t, std::tuple<Handler> handler)-  {-    if (e)-    {-      std::get<0>(handler)(e);-    }-    else-    {-      // Determine the length of the serialized data.-      std::istringstream is(std::string(inbound_header_, header_length));-      std::size_t inbound_data_size = 0;-      if (!(is >> std::hex >> inbound_data_size))-      {-        // Header doesn't seem to be valid. Inform the caller.-        std::error_code error(asio::error::invalid_argument);-        std::get<0>(handler)(error);-        return;-      }--      // Start an asynchronous call to receive the data.-      inbound_data_.resize(inbound_data_size);-      void (connection::*f)(-          const std::error_code&,-          T&, std::tuple<Handler>)-        = &connection::handle_read_data<T, Handler>;-      asio::async_read(socket_, asio::buffer(inbound_data_),-        std::bind(f, this,-          asio::placeholders::error, std::ref(t), handler));-    }-  }--  /// Handle a completed read of message data.-  template <typename T, typename Handler>-  void handle_read_data(const std::error_code& e,-      T& t, std::tuple<Handler> handler)-  {-    if (e)-    {-      std::get<0>(handler)(e);-    }-    else-    {-      // Extract the data structure from the data just received.-      try-      {-        std::string archive_data(&inbound_data_[0], inbound_data_.size());-        std::istringstream archive_stream(archive_data);-        boost::archive::text_iarchive archive(archive_stream);-        archive >> t;-      }-      catch (std::exception& e)-      {-        // Unable to decode data.-        std::error_code error(asio::error::invalid_argument);-        std::get<0>(handler)(error);-        return;-      }--      // Inform caller that data has been received ok.-      std::get<0>(handler)(e);-    }-  }--private:-  /// The underlying socket.-  asio::ip::tcp::socket socket_;--  /// The size of a fixed length header.-  enum { header_length = 8 };--  /// Holds an outbound header.-  std::string outbound_header_;--  /// Holds the outbound data.-  std::string outbound_data_;--  /// Holds an inbound header.-  char inbound_header_[header_length];--  /// Holds the inbound data.-  std::vector<char> inbound_data_;-};--typedef std::shared_ptr<connection> connection_ptr;--} // namespace s11n_example--#endif // SERIALIZATION_CONNECTION_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/serialization/stock.hpp
@@ -1,50 +0,0 @@-//-// stock.hpp-// ~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef SERIALIZATION_STOCK_HPP-#define SERIALIZATION_STOCK_HPP--#include <string>--namespace s11n_example {--/// Structure to hold information about a single stock.-struct stock-{-  std::string code;-  std::string name;-  double open_price;-  double high_price;-  double low_price;-  double last_price;-  double buy_price;-  int buy_quantity;-  double sell_price;-  int sell_quantity;--  template <typename Archive>-  void serialize(Archive& ar, const unsigned int version)-  {-    ar & code;-    ar & name;-    ar & open_price;-    ar & high_price;-    ar & low_price;-    ar & last_price;-    ar & buy_price;-    ar & buy_quantity;-    ar & sell_price;-    ar & sell_quantity;-  }-};--} // namespace s11n_example--#endif // SERIALIZATION_STOCK_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/services/basic_logger.hpp
@@ -1,78 +0,0 @@-//-// basic_logger.hpp-// ~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef SERVICES_BASIC_LOGGER_HPP-#define SERVICES_BASIC_LOGGER_HPP--#include <asio.hpp>-#include <string>--namespace services {--/// Class to provide simple logging functionality. Use the services::logger-/// typedef.-template <typename Service>-class basic_logger-{-public:-  /// The type of the service that will be used to provide timer operations.-  typedef Service service_type;--  /// The native implementation type of the timer.-  typedef typename service_type::impl_type impl_type;--  /// Constructor.-  /**-   * This constructor creates a logger.-   *-   * @param context The execution context used to locate the logger service.-   *-   * @param identifier An identifier for this logger.-   */-  explicit basic_logger(asio::execution_context& context,-      const std::string& identifier)-    : service_(asio::use_service<Service>(context)),-      impl_(service_.null())-  {-    service_.create(impl_, identifier);-  }--  basic_logger(const basic_logger&) = delete;-  basic_logger& operator=(basic_logger&) = delete;--  /// Destructor.-  ~basic_logger()-  {-    service_.destroy(impl_);-  }--  /// Set the output file for all logger instances.-  void use_file(const std::string& file)-  {-    service_.use_file(impl_, file);-  }--  /// Log a message.-  void log(const std::string& message)-  {-    service_.log(impl_, message);-  }--private:-  /// The backend service implementation.-  service_type& service_;--  /// The underlying native implementation.-  impl_type impl_;-};--} // namespace services--#endif // SERVICES_BASIC_LOGGER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/services/logger.hpp
@@ -1,24 +0,0 @@-//-// logger.hpp-// ~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef SERVICES_LOGGER_HPP-#define SERVICES_LOGGER_HPP--#include "basic_logger.hpp"-#include "logger_service.hpp"--namespace services {--/// Typedef for typical logger usage.-typedef basic_logger<logger_service> logger;--} // namespace services--#endif // SERVICES_LOGGER_HPP
− link/modules/asio-standalone/asio/src/examples/cpp11/services/logger_service.hpp
@@ -1,145 +0,0 @@-//-// logger_service.hpp-// ~~~~~~~~~~~~~~~~~~-//-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff 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)-//--#ifndef SERVICES_LOGGER_SERVICE_HPP-#define SERVICES_LOGGER_SERVICE_HPP--#include <asio.hpp>-#include <functional>-#include <fstream>-#include <sstream>-#include <string>-#include <thread>--namespace services {--/// Service implementation for the logger.-class logger_service-  : public asio::execution_context::service-{-public:-  /// The type used to identify this service in the execution context.-  typedef logger_service key_type;--  /// The backend implementation of a logger.-  struct logger_impl-  {-    explicit logger_impl(const std::string& ident) : identifier(ident) {}-    std::string identifier;-  };--  /// The type for an implementation of the logger.-  typedef logger_impl* impl_type;--  /// Constructor creates a thread to run a private io_context.-  logger_service(asio::execution_context& context)-    : asio::execution_context::service(context),-      work_io_context_(),-      work_(asio::make_work_guard(work_io_context_)),-      work_thread_([this]{ work_io_context_.run(); })-  {-  }--  logger_service(const logger_service&) = delete;-  logger_service& operator=(const logger_service&) = delete;;--  /// Destructor shuts down the private io_context.-  ~logger_service()-  {-    /// Indicate that we have finished with the private io_context. Its-    /// io_context::run() function will exit once all other work has completed.-    work_.reset();-    if (work_thread_.joinable())-      work_thread_.join();-  }--  /// Destroy all user-defined handler objects owned by the service.-  void shutdown()-  {-  }--  /// Return a null logger implementation.-  impl_type null() const-  {-    return 0;-  }--  /// Create a new logger implementation.-  void create(impl_type& impl, const std::string& identifier)-  {-    impl = new logger_impl(identifier);-  }--  /// Destroy a logger implementation.-  void destroy(impl_type& impl)-  {-    delete impl;-    impl = null();-  }--  /// Set the output file for the logger. The current implementation sets the-  /// output file for all logger instances, and so the impl parameter is not-  /// actually needed. It is retained here to illustrate how service functions-  /// are typically defined.-  void use_file(impl_type& /*impl*/, const std::string& file)-  {-    // Pass the work of opening the file to the background thread.-    asio::post(work_io_context_,-        std::bind(&logger_service::use_file_impl, this, file));-  }--  /// Log a message.-  void log(impl_type& impl, const std::string& message)-  {-    // Format the text to be logged.-    std::ostringstream os;-    os << impl->identifier << ": " << message;--    // Pass the work of writing to the file to the background thread.-    asio::post(work_io_context_,-        std::bind(&logger_service::log_impl, this, os.str()));-  }--private:-  /// Helper function used to open the output file from within the private-  /// io_context's thread.-  void use_file_impl(const std::string& file)-  {-    ofstream_.close();-    ofstream_.clear();-    ofstream_.open(file.c_str());-  }--  /// Helper function used to log a message from within the private io_context's-  /// thread.-  void log_impl(const std::string& text)-  {-    ofstream_ << text << std::endl;-  }--  /// Private io_context used for performing logging operations.-  asio::io_context work_io_context_;--  /// Work for the private io_context to perform. If we do not give the-  /// io_context some work to do then the io_context::run() function will exit-  /// immediately.-  asio::executor_work_guard<-      asio::io_context::executor_type> work_;--  /// Thread used for running the work io_context's run loop.-  std::thread work_thread_;--  /// The file to which log messages will be written.-  std::ofstream ofstream_;-};--} // namespace services--#endif // SERVICES_LOGGER_SERVICE_HPP
link/modules/asio-standalone/asio/src/examples/cpp11/socks4/socks4.hpp view
@@ -2,7 +2,7 @@ // socks4.hpp // ~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -39,7 +39,7 @@     // Only IPv4 is supported by the SOCKS 4 protocol.     if (endpoint.protocol() != asio::ip::tcp::v4())     {-      throw std::system_error(+      throw asio::system_error(           asio::error::address_family_not_supported);     } 
link/modules/asio-standalone/asio/src/examples/cpp11/type_erasure/line_reader.hpp view
@@ -2,7 +2,7 @@ // line_reader.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -20,7 +20,7 @@ { private:   virtual void async_read_line_impl(std::string prompt,-      asio::any_completion_handler<void(std::error_code, std::string)> handler) = 0;+      asio::any_completion_handler<void(asio::error_code, std::string)> handler) = 0;    struct initiate_read_line   {@@ -37,10 +37,10 @@   template <typename CompletionToken>   auto async_read_line(std::string prompt, CompletionToken&& token)     -> decltype(-        asio::async_initiate<CompletionToken, void(std::error_code, std::string)>(+        asio::async_initiate<CompletionToken, void(asio::error_code, std::string)>(           initiate_read_line(), token, this, prompt))   {-    return asio::async_initiate<CompletionToken, void(std::error_code, std::string)>(+    return asio::async_initiate<CompletionToken, void(asio::error_code, std::string)>(         initiate_read_line(), token, this, prompt);   } };
link/modules/asio-standalone/asio/src/examples/cpp11/type_erasure/sleep.hpp view
@@ -2,7 +2,7 @@ // sleep.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp11/type_erasure/stdin_line_reader.hpp view
@@ -2,7 +2,7 @@ // stdin_line_reader.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -21,7 +21,7 @@  private:   void async_read_line_impl(std::string prompt,-      asio::any_completion_handler<void(std::error_code, std::string)> handler) override;+      asio::any_completion_handler<void(asio::error_code, std::string)> handler) override;    asio::posix::stream_descriptor stdin_;   std::string buffer_;
link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/line_reader.hpp view
@@ -2,7 +2,7 @@ // line_reader.hpp // ~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/sleep.hpp view
@@ -2,7 +2,7 @@ // sleep.hpp // ~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/examples/cpp20/type_erasure/stdin_line_reader.hpp view
@@ -2,7 +2,7 @@ // stdin_line_reader.hpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/tests/latency/allocator.hpp view
@@ -2,7 +2,7 @@ // allocator.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/tests/latency/high_res_clock.hpp view
@@ -2,7 +2,7 @@ // high_res_clock.hpp // ~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/tests/performance/handler_allocator.hpp view
@@ -2,7 +2,7 @@ // handler_allocator.cpp // ~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -12,12 +12,15 @@ #define HANDLER_ALLOCATOR_HPP  #include "asio.hpp"+#include <boost/aligned_storage.hpp>+#include <boost/noncopyable.hpp>  // Class to manage the memory to be used for handler-based custom allocation. // It contains a single block of memory which may be returned for allocation // requests. If the memory is in use when an allocation request is made, the // allocator delegates allocation to the global heap. class handler_allocator+  : private boost::noncopyable { public:   handler_allocator()@@ -25,15 +28,12 @@   {   } -  handler_allocator(const handler_allocator&) = delete;-  handler_allocator& operator=(const handler_allocator&) = delete;-   void* allocate(std::size_t size)   {-    if (!in_use_ && size < sizeof(storage_))+    if (!in_use_ && size < storage_.size)     {       in_use_ = true;-      return storage_;+      return storage_.address();     }      return ::operator new(size);@@ -41,7 +41,7 @@    void deallocate(void* pointer)   {-    if (pointer == storage_)+    if (pointer == storage_.address())     {       in_use_ = false;     }@@ -53,7 +53,7 @@  private:   // Storage space used for handler-based custom memory allocation.-  alignas(std::max_align_t) unsigned char storage_[1024];+  boost::aligned_storage<1024> storage_;    // Whether the handler-based custom allocation storage has been used.   bool in_use_;
link/modules/asio-standalone/asio/src/tests/unit/archetypes/async_ops.hpp view
@@ -1,8 +1,8 @@ //-// archetypes/async_ops.hpp-// ~~~~~~~~~~~~~~~~~~~~~~~~+// async_ops.hpp+// ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -11,448 +11,403 @@ #ifndef ARCHETYPES_ASYNC_OPS_HPP #define ARCHETYPES_ASYNC_OPS_HPP -#include <functional>-#include "asio/associated_allocator.hpp"-#include "asio/associated_executor.hpp"-#include "asio/async_result.hpp"-#include "asio/bind_allocator.hpp"-#include "asio/error.hpp"-#include "asio/post.hpp"+#include <asio/associated_allocator.hpp>+#include <asio/associated_executor.hpp>+#include <asio/async_result.hpp>+#include <asio/error.hpp> +#if defined(ASIO_HAS_BOOST_BIND)+# include <boost/bind/bind.hpp>+#else // defined(ASIO_HAS_BOOST_BIND)+# include <functional>+#endif // defined(ASIO_HAS_BOOST_BIND)+ namespace archetypes { +#if defined(ASIO_HAS_BOOST_BIND)+namespace bindns = boost;+#else // defined(ASIO_HAS_BOOST_BIND) namespace bindns = std;+#endif // defined(ASIO_HAS_BOOST_BIND) -struct initiate_op_0+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void())+async_op_0(ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void()>::completion_handler_type handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void()> completion(token); -    asio::post(ex,-        asio::bind_allocator(a, static_cast<Handler&&>(handler)));-  }-};+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler); -template <typename CompletionToken>-auto async_op_0(CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken, void()>(-      initiate_op_0(), token))-{-  return asio::async_initiate<CompletionToken, void()>(-      initiate_op_0(), token);+  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  ex.post(ASIO_MOVE_CAST(handler_type)(completion.completion_handler), a);++  return completion.result.get(); } -struct initiate_op_ec_0+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(asio::error_code))+async_op_ec_0(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler, bool ok)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(asio::error_code)>::completion_handler_type handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(asio::error_code)> completion(token); -    if (ok)-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              asio::error_code())));-    }-    else-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              asio::error_code(-                asio::error::operation_aborted))));-    }+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler);++  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  if (ok)+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          asio::error_code()), a);   }-};+  else+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          asio::error_code(asio::error::operation_aborted)), a);+  } -template <typename CompletionToken>-auto async_op_ec_0(bool ok, CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken,-      void(asio::error_code)>(-        initiate_op_ec_0(), token, ok))-{-  return asio::async_initiate<CompletionToken,-    void(asio::error_code)>(-      initiate_op_ec_0(), token, ok);+  return completion.result.get(); } -struct initiate_op_ex_0+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr))+async_op_ex_0(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler, bool ok)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(std::exception_ptr)>::completion_handler_type handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(std::exception_ptr)> completion(token); -    if (ok)-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              std::exception_ptr())));-    }-    else-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              std::make_exception_ptr(std::runtime_error("blah")))));-    }+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler);++  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  if (ok)+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          std::exception_ptr()), a);   }-};+  else+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          std::make_exception_ptr(std::runtime_error("blah"))), a);+  } -template <typename CompletionToken>-auto async_op_ex_0(bool ok, CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken,-      void(std::exception_ptr)>(-        initiate_op_ex_0(), token, ok))-{-  return asio::async_initiate<CompletionToken,-    void(std::exception_ptr)>(-      initiate_op_ex_0(), token, ok);+  return completion.result.get(); } -struct initiate_op_1+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int))+async_op_1(ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(int)>::completion_handler_type handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(int)> completion(token); -    asio::post(ex,-        asio::bind_allocator(a,-          bindns::bind(static_cast<Handler&&>(handler), 42)));-  }-};+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler); -template <typename CompletionToken>-auto async_op_1(CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken, void(int)>(-      initiate_op_1(), token))-{-  return asio::async_initiate<CompletionToken, void(int)>(-      initiate_op_1(), token);+  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  ex.post(+      bindns::bind(+        ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+        42), a);++  return completion.result.get(); } -struct initiate_op_ec_1+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+    void(asio::error_code, int))+async_op_ec_1(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler, bool ok)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(asio::error_code, int)>::completion_handler_type+      handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(asio::error_code, int)> completion(token); -    if (ok)-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              asio::error_code(), 42)));-    }-    else-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              asio::error_code(-                asio::error::operation_aborted), 0)));-    }+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler);++  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  if (ok)+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          asio::error_code(), 42), a);   }-};+  else+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          asio::error_code(asio::error::operation_aborted),+          0), a);+  } -template <typename CompletionToken>-auto async_op_ec_1(bool ok, CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken,-      void(asio::error_code, int)>(-        initiate_op_ec_1(), token, ok))-{-  return asio::async_initiate<CompletionToken,-    void(asio::error_code, int)>(-      initiate_op_ec_1(), token, ok);+  return completion.result.get(); } -struct initiate_op_ex_1+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(std::exception_ptr, int))+async_op_ex_1(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler, bool ok)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(std::exception_ptr, int)>::completion_handler_type+      handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(std::exception_ptr, int)> completion(token); -    if (ok)-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              std::exception_ptr(), 42)));-    }-    else-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              std::make_exception_ptr(std::runtime_error("blah")), 0)));-    }+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler);++  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  if (ok)+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          std::exception_ptr(), 42), a);   }-};+  else+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          std::make_exception_ptr(std::runtime_error("blah")), 0), a);+  } -template <typename CompletionToken>-auto async_op_ex_1(bool ok, CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken,-      void(std::exception_ptr, int)>(-        initiate_op_ex_1(), token, ok))-{-  return asio::async_initiate<CompletionToken,-    void(std::exception_ptr, int)>(-      initiate_op_ex_1(), token, ok);+  return completion.result.get(); } -struct initiate_op_2+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double))+async_op_2(ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(int, double)>::completion_handler_type handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(int, double)> completion(token); -    asio::post(ex,-        asio::bind_allocator(a,-          bindns::bind(static_cast<Handler&&>(handler), 42, 2.0)));-  }-};+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler); -template <typename CompletionToken>-auto async_op_2(CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken, void(int, double)>(-      initiate_op_2(), token))-{-  return asio::async_initiate<CompletionToken, void(int, double)>(-      initiate_op_2(), token);+  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  ex.post(+      bindns::bind(+        ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+        42, 2.0), a);++  return completion.result.get(); } -struct initiate_op_ec_2+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+    void(asio::error_code, int, double))+async_op_ec_2(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler, bool ok)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(asio::error_code, int, double)>::completion_handler_type+      handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(asio::error_code, int, double)> completion(token); -    if (ok)-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              asio::error_code(), 42, 2.0)));-    }-    else-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              asio::error_code(asio::error::operation_aborted),-              0, 0.0)));-    }+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler);++  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  if (ok)+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          asio::error_code(), 42, 2.0), a);   }-};+  else+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          asio::error_code(asio::error::operation_aborted),+          0, 0.0), a);+  } -template <typename CompletionToken>-auto async_op_ec_2(bool ok, CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken,-      void(asio::error_code, int, double)>(-        initiate_op_ec_2(), token, ok))-{-  return asio::async_initiate<CompletionToken,-    void(asio::error_code, int, double)>(-      initiate_op_ec_2(), token, ok);+  return completion.result.get(); } -struct initiate_op_ex_2+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+    void(std::exception_ptr, int, double))+async_op_ex_2(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler, bool ok)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(std::exception_ptr, int, double)>::completion_handler_type+      handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(std::exception_ptr, int, double)> completion(token); -    if (ok)-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              std::exception_ptr(), 42, 2.0)));-    }-    else-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              std::make_exception_ptr(std::runtime_error("blah")), 0, 0.0)));-    }+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler);++  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  if (ok)+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          std::exception_ptr(), 42, 2.0), a);   }-};+  else+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          std::make_exception_ptr(std::runtime_error("blah")), 0, 0.0), a);+  } -template <typename CompletionToken>-auto async_op_ex_2(bool ok, CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken,-      void(std::exception_ptr, int, double)>(-        initiate_op_ex_2(), token, ok))-{-  return asio::async_initiate<CompletionToken,-    void(std::exception_ptr, int, double)>(-      initiate_op_ex_2(), token, ok);+  return completion.result.get(); } -struct initiate_op_3+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken, void(int, double, char))+async_op_3(ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(int, double, char)>::completion_handler_type handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(int, double, char)> completion(token); -    asio::post(ex,-        asio::bind_allocator(a,-          bindns::bind(static_cast<Handler&&>(handler), 42, 2.0, 'a')));-  }-};+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler); -template <typename CompletionToken>-auto async_op_3(CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken, void(int, double, char)>(-      initiate_op_3(), token))-{-  return asio::async_initiate<CompletionToken, void(int, double, char)>(-      initiate_op_3(), token);+  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  ex.post(+      bindns::bind(+        ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+        42, 2.0, 'a'), a);++  return completion.result.get(); } -struct initiate_op_ec_3+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+    void(asio::error_code, int, double, char))+async_op_ec_3(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler, bool ok)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(asio::error_code, int, double, char)>::completion_handler_type+      handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(asio::error_code, int, double, char)> completion(token); -    if (ok)-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              asio::error_code(), 42, 2.0, 'a')));-    }-    else-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              asio::error_code(asio::error::operation_aborted),-              0, 0.0, 'z')));-    }+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler);++  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  if (ok)+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          asio::error_code(), 42, 2.0, 'a'), a);   }-};+  else+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          asio::error_code(asio::error::operation_aborted),+          0, 0.0, 'z'), a);+  } -template <typename CompletionToken>-auto async_op_ec_3(bool ok, CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken,-      void(asio::error_code, int, double, char)>(-        initiate_op_ec_3(), token, ok))-{-  return asio::async_initiate<CompletionToken,-    void(asio::error_code, int, double, char)>(-      initiate_op_ec_3(), token, ok);+  return completion.result.get(); } -struct initiate_op_ex_3+template <typename CompletionToken>+ASIO_INITFN_RESULT_TYPE(CompletionToken,+    void(std::exception_ptr, int, double, char))+async_op_ex_3(bool ok, ASIO_MOVE_ARG(CompletionToken) token) {-  template <typename Handler>-  void operator()(Handler&& handler, bool ok)-  {-    typename asio::associated_allocator<Handler>::type a-      = asio::get_associated_allocator(handler);+  typedef typename asio::async_completion<CompletionToken,+    void(std::exception_ptr, int, double, char)>::completion_handler_type+      handler_type; -    typename asio::associated_executor<Handler>::type ex-      = asio::get_associated_executor(handler);+  asio::async_completion<CompletionToken,+    void(std::exception_ptr, int, double, char)> completion(token); -    if (ok)-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              std::exception_ptr(), 42, 2.0, 'a')));-    }-    else-    {-      asio::post(ex,-          asio::bind_allocator(a,-            bindns::bind(static_cast<Handler&&>(handler),-              std::make_exception_ptr(std::runtime_error("blah")),-              0, 0.0, 'z')));-    }+  typename asio::associated_allocator<handler_type>::type a+    = asio::get_associated_allocator(completion.completion_handler);++  typename asio::associated_executor<handler_type>::type ex+    = asio::get_associated_executor(completion.completion_handler);++  if (ok)+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          std::exception_ptr(), 42, 2.0, 'a'), a);   }-};+  else+  {+    ex.post(+        bindns::bind(+          ASIO_MOVE_CAST(handler_type)(completion.completion_handler),+          std::make_exception_ptr(std::runtime_error("blah")),+          0, 0.0, 'z'), a);+  } -template <typename CompletionToken>-auto async_op_ex_3(bool ok, CompletionToken&& token)-  -> decltype(-    asio::async_initiate<CompletionToken,-      void(std::exception_ptr, int, double, char)>(-        initiate_op_ex_3(), token, ok))-{-  return asio::async_initiate<CompletionToken,-    void(std::exception_ptr, int, double, char)>(-      initiate_op_ex_3(), token, ok);+  return completion.result.get(); }  } // namespace archetypes
link/modules/asio-standalone/asio/src/tests/unit/archetypes/async_result.hpp view
@@ -2,7 +2,7 @@ // async_result.hpp // ~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -38,9 +38,11 @@   {   } +#if defined(ASIO_HAS_MOVE)   concrete_handler(concrete_handler&&) {} private:   concrete_handler(const concrete_handler&);+#endif // defined(ASIO_HAS_MOVE) };  template <typename R, typename Arg1, typename Arg2>@@ -65,14 +67,16 @@   {   } -  immediate_executor_type get_immediate_executor() const noexcept+  immediate_executor_type get_immediate_executor() const ASIO_NOEXCEPT   {     return immediate_executor_type();   } +#if defined(ASIO_HAS_MOVE)   immediate_concrete_handler(immediate_concrete_handler&&) {} private:   immediate_concrete_handler(const immediate_concrete_handler&);+#endif // defined(ASIO_HAS_MOVE) };  template <typename Signature>@@ -82,9 +86,11 @@   {   } +#if defined(ASIO_HAS_MOVE)   lazy_concrete_handler(lazy_concrete_handler&&) {} private:   lazy_concrete_handler(const lazy_concrete_handler&);+#endif // defined(ASIO_HAS_MOVE) };  } // namespace archetypes@@ -114,8 +120,8 @@  private:   // Disallow copying and assignment.-  async_result(const async_result&) = delete;-  async_result& operator=(const async_result&) = delete;+  async_result(const async_result&) ASIO_DELETED;+  async_result& operator=(const async_result&) ASIO_DELETED; };  template <typename Signature>@@ -141,8 +147,8 @@  private:   // Disallow copying and assignment.-  async_result(const async_result&) = delete;-  async_result& operator=(const async_result&) = delete;+  async_result(const async_result&) ASIO_DELETED;+  async_result& operator=(const async_result&) ASIO_DELETED; };  } // namespace asio
link/modules/asio-standalone/asio/src/tests/unit/archetypes/gettable_socket_option.hpp view
@@ -2,7 +2,7 @@ // gettable_socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/tests/unit/archetypes/io_control_command.hpp view
@@ -2,7 +2,7 @@ // io_control_command.hpp // ~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/tests/unit/archetypes/settable_socket_option.hpp view
@@ -2,7 +2,7 @@ // settable_socket_option.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)
link/modules/asio-standalone/asio/src/tests/unit/unit_test.hpp view
@@ -2,7 +2,7 @@ // unit_test.hpp // ~~~~~~~~~~~~~ //-// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)+// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff 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)@@ -24,7 +24,7 @@ // Prevent use of intrinsic for strcmp. # include <cstring> # undef strcmp-+  // Suppress error about condition always being true. # pragma option -w-ccc 
src/hs/Sound/Tidal/Link.hsc view
@@ -26,22 +26,22 @@ type Quantum = CDouble  instance Storable AbletonLink where-  alignment _ = #{alignment struct abl_link}-  sizeOf    _ = #{size struct abl_link}+  alignment _ = #{alignment abl_link}+  sizeOf    _ = #{size abl_link}   peek ptr = do-    impl <- #{peek struct abl_link, impl} ptr-    pure (AbletonLink impl)-  poke ptr (AbletonLink impl) =-    #{poke struct abl_link, impl} ptr impl+    impl <- #{peek abl_link,impl} ptr+    return (AbletonLink impl)+  poke ptr (AbletonLink impl) = do+    #{poke abl_link,impl} ptr impl  instance Storable SessionState where-  alignment _ = #{alignment struct abl_link_session_state}-  sizeOf    _ = #{size struct abl_link_session_state}+  alignment _ = #{alignment abl_link_session_state}+  sizeOf    _ = #{size abl_link_session_state}   peek ptr = do-    impl <- #{peek struct abl_link_session_state, impl} ptr-    pure (SessionState impl)-  poke ptr (SessionState impl) =-    #{poke struct abl_link_session_state, impl} ptr impl+    impl <- #{peek abl_link_session_state,impl} ptr+    return (SessionState impl)+  poke ptr (SessionState impl) = do+    #{poke abl_link_session_state,impl} ptr impl  foreign import ccall "abl_link.h abl_link_create"   create :: BPM -> IO AbletonLink
tidal-link.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.4 name:                tidal-link-version:             1.2.1+version:             1.2.2 synopsis:            Ableton Link integration for Tidal -- description: homepage:            http://tidalcycles.org/@@ -46,10 +46,10 @@       -DLINK_PLATFORM_WINDOWS=1 -Wno-multichar   elif os(darwin)     cxx-options:-      -DLINK_PLATFORM_MACOSX=1 -std=c++17 -Wno-multichar -Wno-subobject-linkage+      -DLINK_PLATFORM_MACOSX=1 -std=c++14 -Wno-multichar -Wno-subobject-linkage   else     cxx-options:-      -DLINK_PLATFORM_LINUX=1 -std=c++17 -Wno-multichar -Wno-subobject-linkage+      -DLINK_PLATFORM_LINUX=1 -std=c++14 -Wno-multichar -Wno-subobject-linkage    if impl(ghc >= 9.4)     build-depends: system-cxx-std-lib