ryanhaining / cppitertools Goto Github PK
View Code? Open in Web Editor NEWImplementation of python itertools and builtin iteration functions for C++17
Home Page: https://twitter.com/cppitertools
License: BSD 2-Clause "Simplified" License
Implementation of python itertools and builtin iteration functions for C++17
Home Page: https://twitter.com/cppitertools
License: BSD 2-Clause "Simplified" License
For example slice currently needs a random access iterator. We should detect if one exists for the iterable if it doesn't a different method of using slice should be used
Hi, good to see more Python like functions in c++.
Is it possible to have zip and zip_longest use a single iterator over an arbitrary number of containers that are only known at runtime? Just like in Python when unpacking a list of lists? It would really be helpful for me.
Hello,
as fist step, thanks for this great library!
Now with the issue:
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
auto f = iter::enumerate(v) | iter::filter([](auto& i) { return std::get<1>(i) > 4; });
for (auto&& [i, e]: f) {
std::cout << i << ", " << e << '\n';
}
This snippet doesn't compile (g++ 7.4), with error:
error: use of deleted function ‘std::optional<iter::impl::EnumIterYield<long unsigned int, int&> >& std::optional<iter::impl::EnumIterYield<long unsigned int, int&> >::operator=(std::optional<iter::impl::EnumIterYield<long unsigned int, int&> >&&)’
I opened StackOverflow question, since I'm not sure if I didn't do something wrong - https://stackoverflow.com/questions/57648457/cppitertools-how-to-combine-iterenumerate-and-iterfilter
Is it possible to combine filter with enumerate this way? The solutions appears is to change iterbase.hpp:301
from item_p_ = std::move(item);
to item_p_.emplace(std::move(item));
the build log includes a CMake error:
CMake Error at C:/Program Files (x86)/CMake/share/cmake-3.15/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
Could NOT find Boost (missing: Boost_INCLUDE_DIR) (Required is at least
version "1.60.0")
Call Stack (most recent call first):
C:/Program Files (x86)/CMake/share/cmake-3.15/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
C:/Program Files (x86)/CMake/share/cmake-3.15/Modules/FindBoost.cmake:2161 (find_package_handle_standard_args)
CMakeLists.txt:12 (find_package)
Appveyor only has Boost 1.71.0 for MSVC 2019, but the highest it has for MSVC 2017 is Boost 1.69.0.
The BOOST_ROOT
environment variable in the appveyor setting is set to C:\Libraries\boost_1_64_0
, but of course this only works for MSVC 2017
Both MSVC 2017 and 2019 work when they have their respective correct BOOST_ROOT
This will allow using pointer to member function and pointer to data member arguments.
Hi
I'm getting another strange behaviour:
vector<bool> v{true, true, false, false,false, true, true};
for (auto &&x: iter::groupby(v,[](auto b){return b;})) {
cout << "group: ";
for (auto &&g: x.second)
cout << g << " ";
cout << endl;
}
prints
group: 1 1 0 0 0 1 1
yet
vector<int> v{5,5,5,3,3};
for (auto &&x: iter::groupby(v,[](auto b){return b;})) {
cout << "group: ";
for (auto &&g: x.second)
cout << g << " ";
cout << endl;
}
prints
group: 5 5 5
group: 3 3
Is there a reason why it shouldn't work with bool ?
std::iterator
has been deprecated by C++17. It should be removed in preparation for the future, and replaced with explicit using
declarations.
#include <vector>
#include "zip.hpp"
int main()
{
std::vector<int> a(1);
const auto it = iter::zip(a).begin();
const auto [v] = *it;
return v;
}
[ilya@ilya-pc cppitertools]$ clang++ const_iter.cpp -I ./ -std=c++17 -fno-permissive
const_iter.cpp:11:22: error: indirection requires pointer operand ('const iter::impl::Zipped<std::tuple<std::vector<int, std::allocator > &>, 0>::Iterator<std::tuple<std::vector<int, std::allocator > &>, iterator_tuple_type, iterator_deref_tuple>' invalid)
const auto [v] = *it;
Is there a reason for Zipped::Iterator::operator*() not to be const?
https://github.com/ryanhaining/cppitertools/blob/master/zip.hpp#L90
Give a range object r
r.start()
, r.stop()
, and r.stop()
constexpr member functions to match the .start
, .stop
, and .step
properties.r.size()
and r.length()
to match len(r)
r[index]
I am interested in using this library to iterate over all "n multichoose k" possibilities for a multiset, but I am representing each set as a simple vector of counts, with length n, where all counts add up to k. Is it possible to extract the counts from your iterators without iterating through each "multiset" itself? I had a peek at the headers but I am a bit lost as to how its working exactly.
So using the provided example for combinations_with_replacement
, I would like to get a simple result that would look like:
combinations_with_replacement({1, 2}, 4):
{ 4 0 }
{ 3 1 }
{ 2 2 }
{ 1 3 }
{ 0 4 }
Hi,
I don't know if this counts as a bug. However, here's the issue.
I was trying to use iter::reversed
together with boost::irange
. The following toy example does not compile:
#include <boost/range/irange.hpp>
#include <itertools/reversed.hpp>
int main() {
auto r = boost::irange(0, 10);
for (auto&& i: iter::reversed(r))
std::cout << i << std::endl;
}
the output reads:
error: no member named 'rbegin' in 'boost::integer_range<int>'
decltype(std::declval<Container&>().rbegin());
A workaround could be to use the free functions std::rbegin
and std::rend
, although this would break C++11 compatibility.
Thanks.
I am experiencing problems compiling with gcc-4.9.3. On trying to compile a simple zip
, I get the following error message:
cppitertools/reversed.hpp:29:16: error: 'rbegin' is not a member of 'std'
It seems to me that this issue is due to cppitertools using C++14 features and my standard library not being C++14 compliant, as is explained here.
Should the library still work in a C++11 environment or is there some other problem on my behalf?
Edit:
I now tested with gcc-5.3 and -std=c++11
, which gives similar errors. Activating -std=c++14
fixes the problem.
The issue boils down to:
Implementation of python itertools and builtin iteration functions for C++14
Maintaining everything with duplicate functions that can deduce std::initializer_list
feels like more trouble than it's worth. I doubt anyone makes use of it (I don't), especially because none of the variadic functions can support it and I haven't heard any complaints.
Will be likely be removed alongside the |
operator updates (unless anyone out there says they've used these functions for real).
Hi,
with respect to #16, I was trying to filter out the upper right corner of the matrix using iter::filter
. Here's the showcase code:
int main() {
auto range = iter::product(iter::range(10), iter::range(5));
for (auto&& ij: iter::filter([](std::tuple<unsigned, unsigned> const& c) {return std::get<0>(c) >= std::get<1>(c);}, range))
std::cout << std::get<0>(ij) << "," << std::get<1>(ij) << std::endl;
}
Unfortunately, this does not compile. Clang reads:
error: indirection requires pointer operand ('const iterator_type<iter::Productor<iter::Range<int>, iter::Range<int> > &>' (aka 'const iter::Productor<iter::Range<int>, iter::Range<int> >::Iterator') invalid)
return *this->sub_iter;
Same error if I replace iter::filter
with boost::adaptors::filtered
, so I presume the error should be in iter::Producter
.
Thanks.
Hi. I don't understand the code in the test/test_sorted.cpp:
std::vector<int> ns(3, 9);
for (auto&& n : sorted(ns)) {
n = -1;
}
Vec vc(3, -1);
REQUIRE(ns == vc);
Why so? Doesn't vc must be (-1, -1)? Can you explain?
This simple example fails to compile:
#include <stdlib.h>
#include "cppitertools/chain.hpp"
std::vector<const char *> c1 = {"a", "b", "c"};
std::set<const char *> c2 = {"d", "d", "e"};
for (auto n : iter::chain(c1, c2))
{
std::cout << n << std::endl;
}
The following errors are raised:
in instantiation of function template specialization 'iter::impl::ChainMaker::operator()<std::vector<const char *,
std::allocator<const char *> > &, std::set<const char *, std::less<const char *>, std::allocator<const char *> >
&>' requested here
for (auto n : iter::chain(c1, c2)) {std::cout << n << std::endl;}
^
when you give indices larger than the size of the whole range it can break it
According to https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html, the cmake version config file should be installed alongside the cmake config file; however:
install(EXPORT cppitertools-targets
FILE cppitertools-config.cmake
NAMESPACE cppitertools::
DESTINATION ${cppitertools_INSTALL_CMAKE_DIR}/cppitertools
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cppitertools-config-version.cmake DESTINATION ${cppitertools_INSTALL_CMAKE_DIR})
is how the version file is installed -- afaict, this is a silent failure to use the version file. It seems that the DESTINATION
should probably be ${cppitertools_INSTALL_CMAKE_DIR}/cppitertools
, like the cppitertools-config.cmake
file.
Would it be possible to add support for "repeat" in the product function similar to python?
(https://docs.python.org/2/library/itertools.html#itertools.product)
e.g -- product<4>(A,(4?)) would iterate over the cartesian product of 4 copies of A.
Thanks!
Hi
The following code is a minimal reproducer of an issue I'm getting.
vector<int16_t> v(10000, 0);
auto a = iter::chunked(v,480);
auto b = iter::filter([](auto & chunk){ return true;}, a);
auto c = iter::imap([](auto & chunk){ cout << chunk.size() << " "; return 1;}, b);
for(auto &&x: c);
prints
18446738293966284791 480 480 480 480 480 480 480 480 480 480 480 480 480 480 480 480 480 480 480 400
The first chunk size is always bogus. Inside the first chunk there are also bogus values.
Is this a bug, or I'm I doing something wrong ?
I tried to use reversed in conjunction with zip in a ranged-based for loop, i.e.
for (auto&& tup : reversed(zip(container1, container2))) { ... }
Unfortunately, this results in error messages stating that there is no rbegin() function. Indeed, I didn't find that function in zip.hpp. Are there any plans to add this functionality, possibly also to the other range expressions?
The following statements do not work:
const std::vector<double> expected{1.0, 0.5, 0.0, -0.5, -1.0};
std::vector<double> counted;
for (auto c : count(1.0, -0.5)) {
counted.push_back(c);
if (c <= -1.0) break;
}
for (int i : range(expected.size()))
EXPECT_DOUBLE_EQ(expected[i], counted[i]);
Output errors:
Expected equality of these values: expected[i] Which is: 0 counted[i] Which is: 2.1219957913605248e-313 /home/pedrogf/Projects/LightFields/ReferenceSoftware/REPO/jplm/source/Tests/ThirdParty/CppIterToolsTests.cpp:471: Failure Expected equality of these values: expected[i] Which is: -0.5 counted[i] Which is: 1.0325971998082053e-321 /home/pedrogf/Projects/LightFields/ReferenceSoftware/REPO/jplm/source/Tests/ThirdParty/CppIterToolsTests.cpp:471: Failure Expected equality of these values: expected[i] Which is: -1 counted[i] Which is: 0
However, the equivalent Python code works fine:
import itertools
for i in itertools.count(1.0, -0.5):
print(i)
if i <= -1:
break
1.0 0.5 0.0 -0.5 -1.0
$ g++ examples/zip_examples.cpp -I ./ -std=c++17
In file included from examples/zip_examples.cpp:1:
./zip.hpp: In instantiation of ‘class iter::impl::Zipped<std::tuple<std::vector<int, std::allocator >&, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&>, 0, 1>::Iterator<std::tuple<std::vector<int, std::allocator >&, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&>, iter::impl::iterator_tuple_type, iter::impl::iterator_deref_tuple>’:
examples/zip_examples.cpp:13:46: required from here
./zip.hpp:41:60: error: template parameter ‘template<class TupleType, long unsigned int ...Is> template class IteratorTuple’
template <typename TupleTypeT, template class IteratorTuple,
^~~~~~~~~~~~~
./zip.hpp:46:18: error: redeclared here as ‘template class’
friend class Iterator;
^~~~~~~~
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp --enable-cet=auto
Thread model: posix
gcc version 8.2.1 20180831 (GCC)
I'm not sure how to build and test the project. I've managed to build the tests by running ./download_catch.sh and running scons in the test folder. I can run these tests manually, but I'm sure thats not the proper way.
How should the project be built and tested with Bazel and scons?
Conan is besides Microsoft's vcpkg the most popular package manager for C++ out there. But with good support for cmake and linux in contrast to vcpkg.
We use them it in our C++ projects to pull in dependencies without including them into our source code or installing them on the building system. See for example https://bintray.com/stiffstream/public/restinio%3Astiffstream for how libraries are published on conan.
Would you consider to publish cppitertools on conan? We could help with conanizing cppitertools.
FYI @Shaheen47
Can you please add the list of compatible compilers?
VS 2013 does not support noexcept while VS 2015 finds "unknown size" errors everywhere.
Severity Code Description Project File Line Suppression State
Error C2133 ' ?? ?? :: ?? ::derefers': unknown size ...\include\cppitertools\chain.hpp 72
Hi
I'm getting a segmentation fault with the following code:
std::vector<int> v{true,true,true,false,false,true,true};
auto a = iter::groupby(v,[](bool b){return b;});
auto b = iter::filter([](auto &g){ return g.first;},a);
auto c = iter::imap([](auto &g){ return std::distance(g.second.begin(), g.second.end()); }, b);
for (size_t x: c)
std::cout << x;
I'm trying to get the size of the longest sequence of trues.
Program received signal SIGSEGV, Segmentation fault.
0x00005555556117b1 in __gnu_cxx::operator!=<int*, std::vector<int, std::allocator<int> > > (__lhs=<error reading variable: Cannot access memory at address 0x0>, __rhs=<error reading variable: Cannot access memory at address 0x8>) at /usr/include/c++/8/bits/stl_iterator.h:887
887 { return __lhs.base() != __rhs.base(); }
#0 0x00005555556117b1 in __gnu_cxx::operator!=<int*, std::vector<int, std::allocator<int> > > (__lhs=<error reading variable: Cannot access memory at address 0x0>, __rhs=<error reading variable: Cannot access memory at address 0x8>) at /usr/include/c++/8/bits/stl_iterator.h:887
#1 0x00005555555e99e2 in iter::impl::GroupProducer<std::vector<int, std::allocator<int> >&, main(int, char**)::<lambda(bool)> >::Iterator<std::vector<int, std::allocator<int> >&>::increment_iterator(void) (this=0x0) at /home/miguel/Development/IPL/investigacao/vad_check/cppitertools/groupby.hpp:148
#2 0x00005555555e951b in iter::impl::GroupProducer<std::vector<int, std::allocator<int> >&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&>::GroupIterator::operator++(void) (this=0x7fffffffc520) at /home/miguel/Development/IPL/investigacao/vad_check/cppitertools/groupby.hpp:247
#3 0x00005555555e9088 in std::__distance<iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int>&>::GroupIterator>(iter::impl::GroupProducer<std::vector<int, std::allocator<int> >&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&>::GroupIterator, iter::impl::GroupProducer<std::vector<int, std::allocator<int> >&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&>::GroupIterator, std::input_iterator_tag) (__first=..., __last=...) at /usr/include/c++/8/bits/stl_iterator_base_funcs.h:89
#4 0x00005555555e8843 in std::distance<iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int>&>::GroupIterator>(iter::impl::GroupProducer<std::vector<int, std::allocator<int> >&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&>::GroupIterator, iter::impl::GroupProducer<std::vector<int, std::allocator<int> >&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&>::GroupIterator) (__first=..., __last=...) at /usr/include/c++/8/bits/stl_iterator_base_funcs.h:141
#5 0x00005555555e6d10 in <lambda(auto:5&)>::operator()<std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int>&> > >(std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&> > &) const (__closure=0x7fffffffc870, g={...}) at /home/miguel/Development/IPL/investigacao/vad_check/src/main.cc:456
#6 0x00005555555e90cc in std::__invoke_impl<long int, main(int, char**)::<lambda(auto:5&)>&, std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&> >&>(std::__invoke_other, <lambda(auto:5&)> &, std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&> > &) (__f=..., __args#0={...}) at /usr/include/c++/8/bits/invoke.h:60
#7 0x00005555555e887c in std::__invoke<main(int, char**)::<lambda(auto:5&)>&, std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&> >&>(<lambda(auto:5&)> &, std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&> > &) (__fn=..., __args#0={...}) at /usr/include/c++/8/bits/invoke.h:95
#8 0x00005555555e6d5a in std::__apply_impl<main(int, char**)::<lambda(auto:5&)>&, std::tuple<std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&> >&>, 0>(<lambda(auto:5&)> &, std::tuple<std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&> >&> &&, std::index_sequence) (__f=..., __t=...) at /usr/include/c++/8/tuple:1678
#9 0x00005555555e6d98 in std::apply<main(int, char**)::<lambda(auto:5&)>&, std::tuple<std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&> >&> >(<lambda(auto:5&)> &, std::tuple<std::pair<bool, iter::impl::GroupProducer<std::vector<int>&, main(int, char**)::<lambda(bool)> >::Group<std::vector<int, std::allocator<int> >&> >&> &&) (__f=..., __t=...) at /usr/include/c++/8/tuple:1687
#10 0x00005555555e6e6b in iter::impl::StarMapper<main(int, char**)::<lambda(auto:5&)>, iter::impl::Zipped<std::tuple<iter::impl::Filtered<main(int, char**)::<lambda(auto:4&)>, iter::impl::GroupProducer<std::vector<int, std::allocator<int> >&, main(int, char**)::<lambda(bool)> >&>&>, 0> >::Iterator<iter::impl::Zipped<std::tuple<iter::impl::Filtered<main(int, char**)::<lambda(auto:4&)>, iter::impl::GroupProducer<std::vector<int, std::allocator<int> >&, main(int, char**)::<lambda(bool)> >&>&>, 0> >::operator*(void) (this=0x7fffffffc6f0) at /home/miguel/Development/IPL/investigacao/vad_check/cppitertools/starmap.hpp:86
#11 0x00005555555e7998 in main (argc=3, argv=0x7fffffffd948) at /home/miguel/Development/IPL/investigacao/vad_check/src/main.cc:458
Also, wouldn't it be useful to have a function which calculates the number of elements of an iterator like std::distance(iterator.begin(), iterator.end());
?
For comparison, the same thing in Haskell:
Prelude Data.List> x = [True,True,True,False,False,True]
Prelude Data.List> group x
[[True,True,True],[False,False],[True]]
Prelude Data.List> fmap length $ filter (!!0) $ group x
[3,1]
Prelude Data.List> sortDesc = sortBy (flip compare)
Prelude Data.List> head $ sortDesc $ fmap length $ filter (!!0) $ group x
3
Hi,
I was trying to compose iter::product
with iter::range
so as to iterate over all the coordinate pairs of a matrix. Unfortunately, I can't manage to get it work with iter::range
, wheres there's no problem with ranges generated with boost::irange
. Here's a showcase example:
int main() {
// this work
for (auto&& ij: iter::product(boost::irange(0, 10), boost::irange(0, 5))) {
std::cout << std::get<0>(ij) << "," << std::get<1>(ij) << std::endl;
}
// this does not work
for (auto&& ij: iter::product(iter::range(10), iter::range(5))) {
std::cout << std::get<0>(ij) << "," << std::get<1>(ij) << std::endl;
}
}
clang reports:
note: copy assignment operator of 'Iterator' is implicitly deleted because field 'step' is of const-qualified type 'const int'
const T step;
Thanks and sorry for submitting two reports in a row!
The current implementation of groupby relies on exhausting the elements of each group in order. With Python's groupby, once one tries to access the n+1th group, the nth grouping becomes invalid, so it is not necessary that random accessing of groups be supported.
The C++ implementation does not support short-circuting the evaluation of a group or skipping of a group entirely, a continue
in the outer loop results in unexpected behavior. It must support the C++ equivalent of
for length, group in groupby(words, len):
if length == 4:
continue
for e in group:
print(e)
I'm not sure how to best handle this yet. It seems the logic will have to go either in the Group
class's destructor, or in GroupBy::Iterator::operator++()
Hello,
few time ago I was trying to compile CppIterTools with VS2019 and I get errors with iter::chain
with this kind of errors:
iterbase.hpp(94,36): error C2672: 'iter::impl::get_iters::get_begin': no matching overloaded function found
iterbase.hpp(94,1): error C2893: Failed to specialize function template 'unknown-type iter::impl::get_iters::get_begin(T &)'
iterbase.hpp(104,43): error C2672: 'std::declval': no matching overloaded function found
iterbase.hpp(104,1): error C2893: Failed to specialize function template '_Add_reference<_Ty,void>::_Rvalue std::declval(void) noexcept'
I have filled a bug to Microsoft and they seem to have fix the bug in their compiler on 16.4 version which isn't yet release (maybe a month or 2).
Here is the link:
https://developercommunity.visualstudio.com/content/problem/638663/vs2019-c-failed-to-specialize-sfinae-regression.html
I was able to get the begin iterator for range to work:
auto r = iter::range(5);
auto first = r.begin();
But I can't get product to compile:
std::string s = "abc";
auto p = iter::product(s,s);
auto first = p.begin();
This was compiled on Visual Studio 2017.
Here's the error message:
1>main.cpp
1>d:\visual studio 2017\itertools_test\cppitertools\internal\iterbase.hpp(75): error C2672: 'iter::impl::get_iters::get_begin': no matching overloaded function found
1>d:\visual studio 2017\itertools_test\cppitertools\internal\iterbase.hpp(85): note: see reference to alias template instantiation 'iterator_type' being compiled
1>d:\visual studio 2017\itertools_test\cppitertools\product.hpp(39): note: see reference to alias template instantiation 'iterator_deref' being compiled
1>d:\visual studio 2017\itertools_test\cppitertools\product.hpp(54): note: see reference to alias template instantiation 'ProdIterDeref<std::basic_string<char,std::char_traits,std::allocator>&>' being compiled
1>d:\visual studio 2017\itertools_test\product_test\product_test\main.cpp(18): note: see reference to class template instantiation 'iter::impl::Productor<std::string &,std::string &>::IteratorTempl<Container,iter::impl::Productor<std::string &>::IteratorTempl<Container,iter::impl::Productor<>::Iterator>>' being compiled
1> with
1> [
1> Container=std::string &
1> ]
1>d:\visual studio 2017\itertools_test\cppitertools\internal\iterbase.hpp(75): error C2893: Failed to specialize function template 'unknown-type iter::impl::get_iters::get_begin(T &)'
1>d:\visual studio 2017\itertools_test\cppitertools\internal\iterbase.hpp(75): note: With the following template arguments:
1>d:\visual studio 2017\itertools_test\cppitertools\internal\iterbase.hpp(75): note: 'T=add_rvalue_reference<_Ty>::type'
1>d:\visual studio 2017\itertools_test\cppitertools\internal\iterbase.hpp(85): error C2672: 'std::declval': no matching overloaded function found
1>d:\visual studio 2017\itertools_test\cppitertools\internal\iterbase.hpp(85): error C2893: Failed to specialize function template 'add_rvalue_reference<_Ty>::type std::declval(void) noexcept'
1>d:\visual studio 2017\itertools_test\cppitertools\internal\iterbase.hpp(85): note: With the following template arguments:
1>d:\visual studio 2017\itertools_test\cppitertools\internal\iterbase.hpp(85): note: '_Ty=unknown-type &'
1>d:\visual studio 2017\itertools_test\cppitertools\product.hpp(39): error C3546: '...': there are no parameter packs available to expand
1>d:\visual studio 2017\itertools_test\cppitertools\product.hpp(54): error C3203: 'tuple': unspecialized class template can't be used as a template argument for template parameter '_Ty', expected a real type
1>d:\visual studio 2017\itertools_test\cppitertools\product.hpp(58): error C2512: 'std::is_same<unknown-type,unknown-type>': no appropriate default constructor available
1>d:\visual studio 2017\itertools_test\cppitertools\product.hpp(58): note: The target type has no constructors
1>d:\visual studio 2017\itertools_test\cppitertools\product.hpp(108): error C3203: 'tuple': unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type
I am trying to translate this (simplified) example from python (2.7) to C++ (tried both clang 3.4 and gcc 4.7) using move-only objects.
Python snippet, prints 41 43
:
import itertools as it
class MyItem:
def __init__(self, val):
self.val = val
def with_val(self, val):
self.val = val
return self
if "__main__" == __name__:
vec = [MyItem(41), MyItem(42), MyItem(43)]
transformed1 = it.imap(lambda el: el.with_val(el.val + 10), vec)
filtered = it.ifilter(lambda el: 52 != el.val, transformed1)
transformed2 = it.imap(lambda el: el.with_val(el.val - 10), filtered)
for el in transformed2:
print(el.val)
C++ snippet, prints 51 53
:
#include <iostream>
#include <vector>
#include "imap.hpp"
#include "filter.hpp"
class MyMoveOnly {
int val;
public:
MyMoveOnly() { };
MyMoveOnly(int val) : val(val) { }
MyMoveOnly(const MyMoveOnly&) = delete;
MyMoveOnly& operator=(const MyMoveOnly&) = delete;
MyMoveOnly(MyMoveOnly&& other) : val(other.val) { }
MyMoveOnly& operator=(MyMoveOnly&& other) {
this->val = other.val;
return *this;
}
int get_val() {
return val;
}
void set_val(int val) {
this->val = val;
}
};
namespace it = iter;
int main() {
// source data
std::vector<MyMoveOnly> vec{};
vec.emplace_back(MyMoveOnly(41));
vec.emplace_back(MyMoveOnly(42));
vec.emplace_back(MyMoveOnly(43));
// some transformations
auto transformed1 = it::imap([](MyMoveOnly& el) {
int va = el.get_val();
el.set_val(va + 10);
return std::move(el);
}, vec);
// r-value ref is used here because l-value ref won't compile
auto filtered = it::filter([](MyMoveOnly&& el) {
return 52 != el.get_val();
}, transformed1);
auto transformed2 = it::imap([](MyMoveOnly& el) {
int va = el.get_val();
el.set_val(va - 10);
return std::move(el);
}, filtered);
// print data
for (auto&& el : transformed2) {
std::cout << el.get_val() << std::endl;
}
return 0;
}
I wasn't sure that this example will compile (because of non-copyable objects), it actually compiles and runs, but the first transformation is applied twice for each element. I am not sure whether this is intended behaviour, but it is definitely contr-intuitive because single foreach over the transformed sequence caused multiple applyings of imap function.
We have a whole testing directory right now and the tests are fine. But I want to adapt them to use the boost unit test framework, this will make the tests more useful by actually checking something instead of just running and exiting
In the older version of imap
, which was not implemented on top of starmap
, you could say something like
auto fn = []{};
using MapType = decltype(iter::imap(fn, 1));
MapType
isn't terribly useful here, you couldn't actually iterate through it, but the behavior is consistent with most other itertools. In the new version, the above code fails to compile.
iterbase.hpp
uses std::enable_if_t
, which was not added until C++14. The repository description indicates that this is a C++11 library, and nowhere in the readme does it mention that C++14 support is required.
Hi,
Often, I find myself mixing together cppitertools and boost.range (and – more recently – range-v3). I believe that supporting the (de-facto standard) pipe operator |
would greatly improve the interoperability between the different range libraries.
Thanks.
First, I love this library. As soon as I first read of range-based for loops, I wanted this. Now, the feature request...
It would be great to have a way to transform all of the elements in an iterator, as is often done with list comprehensions in python.
for (auto&& p : transform([](int x) { return x*x; }, range(10))) { /* ... */ }
or
for (auto&& p : range(10) | transform([](int x) { return x*x; })) { /* ... */ }
If there is some magic in C++ to do this already, perhaps that can go as an example in the readme.
As discussed here: bazelbuild/bazel#7662
Hi.
Gr8 library.
It would be very helpful if all includes used "" instead of <>. That way, there is no need to add the entire cppitertools directory to the include path, e.g. It would be better to just drop the entire library in the regular include path and just do
and everything will work.
Hi, I am trying to group_by a tuple key:
struct A {
int key1;
int key2;
int x;
int y;
int value;
};
void func() {
using namespace std;
// inputs
std::vector<int> uniquex{ 1, 2 };
std::vector<int> uniquey{ 1, 2 };
vector<A> vec{
{ 10, 9, 1, 1, 5 }, { 10, 9, 1, 2, 6 },
{ 10, 10, 1, 1, 1 }, { 10, 10, 1, 2, 2 },
{ 10, 9, 2, 1, 7 }, { 10, 9, 2, 2, 8 },
{ 10, 10, 2, 1, 3 }, { 10, 10, 2, 2, 4 },
};
auto keyFunc = [](const A& a) { return make_tuple(a.key1, a.key2); };
for (auto&& gb : iter::groupby(vec, keyFunc)) {
std::cout << "key(" << std::get<0>(gb.first) << "," << std::get<1>(gb.first) << "): ";
for (auto&& s : gb.second) {
std::cout << s.value << " ";
}
std::cout << '\n';
}
Instead of printing 2 lines, this example prints four lines. Does the groupby intent to work with group data not next to each other?
Hi,
I would like to use the library with move only types. Here's a toy example:
#include <iostream>
#include <vector>
#include <itertools/product.hpp>
struct MoveOnlyType {
MoveOnlyType() = default;
MoveOnlyType(MoveOnlyType const& other) = delete;
MoveOnlyType(MoveOnlyType&& other) = default;
MoveOnlyType& operator=(MoveOnlyType const& other) = delete;
MoveOnlyType& operator=(MoveOnlyType&& other) = default;
};
int main() {
std::vector<MoveOnlyType> v1, v2;
v1.push_back(MoveOnlyType());
v1.push_back(MoveOnlyType());
v2.push_back(MoveOnlyType());
v2.push_back(MoveOnlyType());
v2.push_back(MoveOnlyType());
for (auto&& pair_of_moveonly: iter::product(v1, v2))
std::cout << "it does not work" << std::endl;
}
Thanks.
I have noted that your the container class must have a .begin()
method otherwise you cannot declare the iterators. However, if you use declvar any iterable that support std::begin() (like static arrays) will also work in your framework. For instance, here's how I would declare a typedef for iterator_type:
typedef decltype(std::begin(std::declval<Iterable&>())) iterator_type;
Now the iterable can be:
The following fails, can't construct the iterator
#include <vector>
#include "cppitertools/chain.hpp"
int main() {
std::vector<char> v1 = {'a'};
std::vector<char> v2 = {'b'};
const auto ch = iter::chain(v1, v2);
std::begin(ch);
}
Because the chain begin() const
is saying that the iterator needs a const tuple<Ts...>
while what it actually gets is tuple<const Ts...>
This is just a little nitpick, but I was reading you code base and realized that iter::count is doing limit checking and the explanation is a bit off
Effectively a range without a stopping point.
Although in signed integers overflow is undefined, it is defined in unsigned integers as wraparound but the below loop ends at 65534. (One before the limit)
using T = unsigned short;
for(auto i : iter::count(T{})) {
if(cond)
break;
}
I think more reasonable behaviour is just incrementing the counter by step at each iteration without doing a boundary check and let it fail if it ever hits an undefined behaviour. In here you are basically defining the behaviour.
However as I said at the beginning, this is just a little nitpick regarding the documentation and it would be still fine to keep the behaviour as it is but with proper explanation in the documentation.
it seems like "public: " was forgotten.
as is, the examples obviously fail to compile.
Hi,
I tried to build the test code on OSX,
but a lot of the builds, which include functional.h
fail with the error below.
I have not found a way to fix this yet, but if you have any suggestions where to start it would be appreciated.
Regards
Jiri
System:
$ uname -a
Darwin JiriMBP.home 14.4.0 Darwin Kernel Version 14.4.0: Thu May 28 11:35:04 PDT 2015; root:xnu-2782.30.5~1/RELEASE_X86_64 x86_64 i386 MacBookPro11,2 Darwin
$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix
c++ -o test_combinations.o -c -g -Wall -Wextra -std=c++11 -fdiagnostics-color=always -I/usr/local/include -I. -I/Users/Jiri/Documents/lib/cpp/iter/cppitertools test_combinations.cpp
In file included from test_combinations.cpp:1:
In file included from ./helpers.hpp:4:
In file included from /Users/Jiri/Documents/lib/cpp/iter/cppitertools/iterbase.hpp:13:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:477:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1645:31: error: no matching constructor for
initialization of 'std::__1::vector<char, std::__1::allocator<char> >'
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1572:18: note: in instantiation of function
template specialization 'std::__1::allocator<std::__1::vector<char, std::__1::allocator<char> > >::construct<std::__1::vector<char,
std::__1::allocator<char> >, iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>,
iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long> >' requested here
{__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1453:14: note: in instantiation of function
template specialization 'std::__1::allocator_traits<std::__1::allocator<std::__1::vector<char, std::__1::allocator<char> > >
>::__construct<std::__1::vector<char, std::__1::allocator<char> >, iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>,
iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long> >' requested here
{__construct(__has_construct<allocator_type, pointer, _Args...>(),
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1633:25: note: in instantiation of function
template specialization 'std::__1::allocator_traits<std::__1::allocator<std::__1::vector<char, std::__1::allocator<char> > >
>::construct<std::__1::vector<char, std::__1::allocator<char> >, iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>,
iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long> >' requested here
__alloc_traits::construct(this->__alloc(),
^
test_combinations.cpp:21:12: note: in instantiation of function template specialization 'std::__1::vector<std::__1::vector<char, std::__1::allocator<char> >,
std::__1::allocator<std::__1::vector<char, std::__1::allocator<char> > >
>::emplace_back<iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>,
iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long> >' requested here
sc.emplace_back(std::begin(v), std::end(v));
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:521:5: note: candidate constructor not viable:
no known conversion from 'iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>' to 'size_type' (aka 'unsigned long') for
1st argument
vector(size_type __n, const_reference __x);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:555:5: note: candidate constructor not viable:
no known conversion from 'iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>' to 'initializer_list<value_type>' for 1st
argument
vector(initializer_list<value_type> __il, const allocator_type& __a);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:566:5: note: candidate constructor not viable:
no known conversion from 'iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>' to 'const std::__1::vector<char,
std::__1::allocator<char> >' for 1st argument
vector(const vector& __x, const allocator_type& __a);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:574:5: note: candidate constructor not viable:
no known conversion from 'iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>' to
'std::__1::vector<char, std::__1::allocator<char> >' for 1st argument
vector(vector&& __x, const allocator_type& __a);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:525:35: note: candidate template ignored:
disabled by 'enable_if' [with _InputIterator = iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>]
typename enable_if<__is_input_iterator <_InputIterator>::value &&
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:540:35: note: candidate template ignored:
disabled by 'enable_if' [with _ForwardIterator = iter::IteratorIterator<std::__1::__wrap_iter<std::__1::__wrap_iter<char *> *>, long>]
typename enable_if<__is_forward_iterator<_ForwardIterator>::value &&
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:532:9: note: candidate constructor template not
viable: requires at least 3 arguments, but 2 were provided
vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:546:9: note: candidate constructor template not
viable: requires at least 3 arguments, but 2 were provided
vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:510:40: note: candidate constructor not viable:
requires single argument '__a', but 2 arguments were provided
_LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:517:14: note: candidate constructor not viable:
requires single argument '__n', but 2 arguments were provided
explicit vector(size_type __n);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:553:5: note: candidate constructor not viable:
requires single argument '__il', but 2 arguments were provided
vector(initializer_list<value_type> __il);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:565:5: note: candidate constructor not viable:
requires single argument '__x', but 2 arguments were provided
vector(const vector& __x);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:571:5: note: candidate constructor not viable:
requires single argument '__x', but 2 arguments were provided
vector(vector&& __x)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:522:5: note: candidate constructor not viable:
requires 3 arguments, but 2 were provided
vector(size_type __n, const_reference __x, const allocator_type& __a);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:503:5: note: candidate constructor not viable:
requires 0 arguments, but 2 were provided
vector()
^
1 error generated.
scons: *** [test_combinations.o] Error 1
scons: building terminated because of errors.
Currently this is invalid with c++17
for (auto&& [i, e] : iter::enumerate(seq)) {
// ...
}
because the object returned by enumerate's iterator's operator*
is a subclass of pair with more data members. In some way, the above should work.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.