Search code examples
c++boostiteratorstd-rangestype-constraints

Creating std subrange from boost archive iterators


I'm using Boost's archive iterators to encode and decode base64, I can create a pair of iterators that represent an encoded string and use them to constuct types like std::string no problem. The problem arises when I try to use these iterators to construct a std::ranges::subrange, the compiler tells me that the iterators do not satisfy the constraints for the class template.

using namespace boost::archive::iterators;
using encode = base64_from_binary<transform_width<std::string::iterator, 6, 8>>;

std::string s("Hello World!");

encode b(s.begin());
encode e(s.end());

// works no problem, prints base64 encoded text
std::string output_string(b, e);
std::cout << output_string << std::endl;

// fails as constraints were not satisfied for the template
std::ranges::subrange<encode> output_range(b, e);

I've tried specifying the templates arguments a number of ways, but always get the following error. error C7602: 'std::ranges::subrange': the associated constraints are not satisfied.

The full errror message being

====================[ Build | BASE64TEST | Debug ]==============================
C:\Users\me\AppData\Local\Programs\CLion\bin\cmake\win\x64\bin\cmake.exe --build C:\Users\me\CLionProjects\untitled7\cmake-build-debug --target BASE64TEST -j 10
[1/2] Building CXX object CMakeFiles\BASE64TEST.dir\base64.cpp.obj
FAILED: CMakeFiles/BASE64TEST.dir/base64.cpp.obj 
C:\PROGRA~2\MICROS~4\2019\BUILDT~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\cl.exe  /nologo /TP  -IC:\Users\me\CLionProjects\untitled7 -I"C:\Program Files\boost\boost_1_82_0" /DWIN32 /D_WINDOWS /EHsc /Ob0 /Od /RTC1 -std:c++latest -MDd -Zi /showIncludes /FoCMakeFiles\BASE64TEST.dir\base64.cpp.obj /FdCMakeFiles\BASE64TEST.dir\ /FS -c C:\Users\me\CLionProjects\untitled7\base64.cpp
C:\Users\me\CLionProjects\untitled7\base64.cpp(64): error C7602: 'std::ranges::subrange': the associated constraints are not satisfied
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\include\xutility(3370): note: see declaration of 'std::ranges::subrange'
C:\Users\me\CLionProjects\untitled7\base64.cpp(64): error C2641: cannot deduce template arguments for 'std::ranges::subrange'
C:\Users\me\CLionProjects\untitled7\base64.cpp(64): error C2783: 'std::ranges::subrange<_It,_Se,_Ki> std::ranges::subrange(std::true_type,_Rng &&)': could not deduce template argument for '_It'
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\include\xutility(3383): note: see declaration of 'std::ranges::subrange'
C:\Users\me\CLionProjects\untitled7\base64.cpp(64): error C2780: 'std::ranges::subrange<_It,_Se,_Ki> std::ranges::subrange(std::ranges::subrange<_It,_Se,_Ki>)': expects 1 arguments - 2 provided
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\include\xutility(3370): note: see declaration of 'std::ranges::subrange'
ninja: build stopped: subcommand failed.


Solution

  • The constraint that isn't satisfied seems to be std::weakly_incrementable, specifically the requirement

    { ++i } -> std::same_as<I&>;
    

    This is because base64_from_binary inherits operator++ from boost::iterators::transform_iterator, and doesn't implement it's own.

    This means base64_from_binary isn't going to interoperate with anything constrained on C++20 iterator constraints, but will interoperate with things specified in earlier standards.