csv-parser icon indicating copy to clipboard operation
csv-parser copied to clipboard

StreamParser compilation error with some stream sources

Open addy90 opened this issue 10 months ago • 0 comments

I have encountered a small error in the StreamParser class: https://github.com/vincentlaucsb/csv-parser/blob/bc9131e284bc9244b1452b343d59c7ca8a880811/include/internal/basic_csv_parser.hpp#L301

Both constructors take a reference to the TStream: https://github.com/vincentlaucsb/csv-parser/blob/bc9131e284bc9244b1452b343d59c7ca8a880811/include/internal/basic_csv_parser.hpp#L305 https://github.com/vincentlaucsb/csv-parser/blob/bc9131e284bc9244b1452b343d59c7ca8a880811/include/internal/basic_csv_parser.hpp#L311

But they move it into a non-reference variable, which ultimately leads to a copy of the reference: https://github.com/vincentlaucsb/csv-parser/blob/bc9131e284bc9244b1452b343d59c7ca8a880811/include/internal/basic_csv_parser.hpp#L360

This gives compilation errors with some (third-party) stream sources that have (or refer to) deleted copy assignment constructors (of base classes).

I suggest to fix this by setting the variable to a reference: from TStream _source; to: TStream& _source;

And remove the std::move operators in the constructor assignments, as they are no longer needed for the reference copy: https://github.com/vincentlaucsb/csv-parser/blob/bc9131e284bc9244b1452b343d59c7ca8a880811/include/internal/basic_csv_parser.hpp#L308 https://github.com/vincentlaucsb/csv-parser/blob/bc9131e284bc9244b1452b343d59c7ca8a880811/include/internal/basic_csv_parser.hpp#L315

Then it should work with any stream source that is defined and given to CSVReader, even with those who can not be copied, not only std::ifstream.

Here is a Compiler Explorer example: https://godbolt.org/z/Ea6fr5bG9 With the regular version of this project (2.3.0) the compilation fails because of use of deleted function:

Compilation error log
In file included from <source>:9:
/app/csv.hpp: In instantiation of 'csv::internals::StreamParser<TStream>::StreamParser(TStream&, const csv::CSVFormat&, const csv::internals::ColNamesPtr&) [with TStream = boost::iostreams::filtering_stream<boost::iostreams::input>; csv::internals::ColNamesPtr = std::shared_ptr<csv::internals::ColNames>]':
/app/csv.hpp:6337:17:   required from 'csv::CSVReader::CSVReader(TStream&, csv::CSVFormat) [with TStream = boost::iostreams::filtering_stream<boost::iostreams::input>; typename std::enable_if<std::is_base_of<std::basic_istream<char>, TStream>::value, int>::type <anonymous> = 0]'
 6337 |                 new Parser(source, format, col_names)); // For C++11
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:23:20:   required from 'void parse_csv(Input&) [with Input = boost::iostreams::filtering_stream<boost::iostreams::input>]'
   23 |     csv::CSVReader csv(input, format);
      |                    ^~~
<source>:51:14:   required from here
   51 |     parse_csv(input2);
      |     ~~~~~~~~~^~~~~~~~
/app/csv.hpp:6147:53: error: use of deleted function 'boost::iostreams::filtering_stream<boost::iostreams::input>::filtering_stream(const boost::iostreams::filtering_stream<boost::iostreams::input>&)'
 6147 |             ) : IBasicCSVParser(format, col_names), _source(std::move(source)) {};
      |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from <source>:7:
/app/boost/include/boost/iostreams/filtering_stream.hpp:169:1: note: 'boost::iostreams::filtering_stream<boost::iostreams::input>::filtering_stream(const boost::iostreams::filtering_stream<boost::iostreams::input>&)' is implicitly deleted because the default definition would be ill-formed:
  169 | BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(filtering_stream, boost::iostreams::chain, char)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/iostreams/filtering_stream.hpp:169:1: error: use of deleted function 'boost::iostreams::detail::filtering_stream_base<boost::iostreams::chain<boost::iostreams::input, char, std::char_traits<char>, std::allocator<char> >, boost::iostreams::public_>::filtering_stream_base(const boost::iostreams::detail::filtering_stream_base<boost::iostreams::chain<boost::iostreams::input, char, std::char_traits<char>, std::allocator<char> >, boost::iostreams::public_>&)'
/app/boost/include/boost/iostreams/filtering_stream.hpp:72:7: note: 'boost::iostreams::detail::filtering_stream_base<boost::iostreams::chain<boost::iostreams::input, char, std::char_traits<char>, std::allocator<char> >, boost::iostreams::public_>::filtering_stream_base(const boost::iostreams::detail::filtering_stream_base<boost::iostreams::chain<boost::iostreams::input, char, std::char_traits<char>, std::allocator<char> >, boost::iostreams::public_>&)' is implicitly deleted because the default definition would be ill-formed:
   72 | class filtering_stream_base
      |       ^~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/iostreams/filtering_stream.hpp:72:7: error: use of deleted function 'std::basic_istream<_CharT, _Traits>::basic_istream(const std::basic_istream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
In file included from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/fstream:40,
                 from <source>:1:
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/istream:701:7: note: declared here
  701 |       basic_istream(const basic_istream&) = delete;
      |       ^~~~~~~~~~~~~
/app/boost/include/boost/iostreams/filtering_stream.hpp:72:7: note: use '-fdiagnostics-all-candidates' to display considered candidates
   72 | class filtering_stream_base
      |       ^~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/iostreams/filtering_stream.hpp:72:7: error: use of deleted function 'std::basic_ios<_CharT, _Traits>::basic_ios(const std::basic_ios<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
In file included from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/ios:46,
                 from /opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/istream:40:
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/basic_ios.h:479:7: note: declared here
  479 |       basic_ios(const basic_ios&) = delete;
      |       ^~~~~~~~~
/app/boost/include/boost/iostreams/filtering_stream.hpp:72:7: note: use '-fdiagnostics-all-candidates' to display considered candidates
   72 | class filtering_stream_base
      |       ^~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/iostreams/filtering_stream.hpp:169:1: note: use '-fdiagnostics-all-candidates' to display considered candidates
  169 | BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(filtering_stream, boost::iostreams::chain, char)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/app/boost/include/boost/iostreams/filtering_stream.hpp:169:1: error: use of deleted function 'std::basic_ios<_CharT, _Traits>::basic_ios(const std::basic_ios<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/bits/basic_ios.h:479:7: note: declared here
  479 |       basic_ios(const basic_ios&) = delete;
      |       ^~~~~~~~~
/app/boost/include/boost/iostreams/filtering_stream.hpp:169:1: note: use '-fdiagnostics-all-candidates' to display considered candidates
  169 | BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(filtering_stream, boost::iostreams::chain, char)
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/app/csv.hpp:6147:53: note: use '-fdiagnostics-all-candidates' to display considered candidates
 6147 |             ) : IBasicCSVParser(format, col_names), _source(std::move(source)) {};
      |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~
Compiler returned: 1

When you exchange the #include "csv.hpp" with the proposed fix #include "csv-fixed.hpp" the compilation and code execution works for all test cases.

Thank you!

addy90 avatar Feb 11 '25 16:02 addy90