# Iterating over CxxWrap-ed vector

**URL:** <https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576>\
**Category:** New to Julia\
**Tags:** cxx, cxxwrap\
**Created:** [March 7, 2019, 3:14pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576 "2019-03-07T15:14:24Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Josiah\_Slack](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josiah_slack/32/8319_2.png) [@Josiah\_Slack](https://discourse.julialang.org/u/Josiah_Slack)\
**Post date:** [March 7, 2019, 3:14pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/1 "2019-03-07T15:14:24Z")

</div>

I’m experimenting with CxxWrap, and within my C++ code, I’m defining a class called Point2D. One of the things I want to do is to wrap a std::vector and then iterate over it on the Julia side. In my C++, I’ve got code that looks like:

```

    JLCXX_MODULE define_point2d_module(jlcxx::Module& types) {
        .
        .
        .
        types.add_type("PointVec")
             .method("length", &PointVec::size)
             .method("getindex", [][const PointVec& vec, size_t index) {
                                                 return vec.at(index);
                                             });
         .
         .
         .
     }

```

What is mysterious to me is how to implement a Julia iterator over my PointVec type. I’ve looked at descriptions of how to write Julia iterators, but it’s not at all clear how I’d connect my PointVec methods.

---

<div class="post-metadata">

**Author:** ![jstrube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jstrube/32/525_2.png) [@jstrube](https://discourse.julialang.org/u/jstrube)\
**Post date:** [March 7, 2019, 4:51pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/2 "2019-03-07T16:51:07Z")

</div>

I’ve implemented something similar in my package. Maybe code like this can help:

> <https://github.com/jstrube/LCIO.jl/blob/main/src/LCIO.jl#L39>

---

<div class="post-metadata">

**Author:** ![Josiah\_Slack](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josiah_slack/32/8319_2.png) [@Josiah\_Slack](https://discourse.julialang.org/u/Josiah_Slack)\
**Post date:** [March 7, 2019, 6:06pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/3 "2019-03-07T18:06:28Z")

</div>

Thank you! This definitely looks promising. I’m experimenting in the REPL, and get a Julia error when I try to iterate over one of my PointVec objects:

```

ERROR: MethodError: no method matching size(::Main.Point2DWrapper.PointVecAllocated)

```

I’m using Julia 1.1.0, if that is relevant. Is there some additional export I need to do to bring “size” (and presumably “at”) into the current namespace?

---

<div class="post-metadata">

**Author:** ![jstrube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jstrube/32/525_2.png) [@jstrube](https://discourse.julialang.org/u/jstrube)\
**Post date:** [March 7, 2019, 9:01pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/4 "2019-03-07T21:01:38Z")

</div>

`size` and `at` are the names on the C++ side.  
Your code already translates that correctly to the Julia nomenclature `length` and `getindex`, so you want to use those names.

In other words, I think you only need lines 39 and 40 above, and you can ignore the rest.  
(And you’ll want to replace `StdVecs` with `PointVec`)

---

<div class="post-metadata">

**Author:** ![Josiah\_Slack](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josiah_slack/32/8319_2.png) [@Josiah\_Slack](https://discourse.julialang.org/u/Josiah_Slack)\
**Post date:** [March 7, 2019, 9:35pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/5 "2019-03-07T21:35:16Z")

</div>

Actually, I’ve got another vector type, so I did find it useful to mimic your StdVecs approach

```

import Base: getindex, length, convert, iterate

const StdVecs = Union{PointVec, PolygonVec}
iterate(it::StdVecs) = length(it) > 0 ? (it[1], 2) : nothing
iterate(it::StdVecs, i) = i <= length(it) ? (it[i], i+1) : nothing
length(it::StdVecs) = size(it)
getindex(it::StdVecs, i) = at(it, convert(Uint64, i - 1))
eltype(::Type{PointVec}) = Point2D
eltype(::Type{PolygonVec}) = Polygon2D

```

In case this provides a clue, here’s what I’m doing to import the CxxWrap types:

```

module Scene

module Point2DWrapper
using CxxWrap
@wrapmodule("libboost_wrap", :define_point2d_module)
function __init__ ()
    @initcxx
end
export Point2D, PointVec, getx, gety, size, at
end
using Scene.Point2DWrapper

```

I’ve tried both explicitly exporting ‘size’ and ‘at’, and leaving them out of the export statement, which is why I was referring to “current namespace” in my previous post.  
Thanks again for your help with this.

---

<div class="post-metadata">

**Author:** ![jstrube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jstrube/32/525_2.png) [@jstrube](https://discourse.julialang.org/u/jstrube)\
**Post date:** [March 7, 2019, 10:18pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/6 "2019-03-07T22:18:20Z")

</div>

I don’t think exporting is your problem. Your code maps the C++ `size` to Julia’s `length`.  
`size` is just not a known name on the Julia side.  
Just leave your C++ code as is and get rid of `size` and `at` on the Julia side completely.

---

<div class="post-metadata">

**Author:** ![jstrube](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jstrube/32/525_2.png) [@jstrube](https://discourse.julialang.org/u/jstrube)\
**Post date:** [March 7, 2019, 10:19pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/7 "2019-03-07T22:19:48Z")

</div>

In other words, remove these two lines

> [@Josiah\_Slack](#):
>
> length(it::StdVecs) = size(it)  
> getindex(it::StdVecs, i) = at(it, convert(Uint64, i - 1))

---

<div class="post-metadata">

**Author:** ![Josiah\_Slack](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josiah_slack/32/8319_2.png) [@Josiah\_Slack](https://discourse.julialang.org/u/Josiah_Slack)\
**Post date:** [March 8, 2019, 2:14pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/8 "2019-03-08T14:14:52Z")

</div>

That doesn’t seem to do it. The error message I get is now:

```

ERROR: LoadError: MethodError: no method matching length(::Main.Point2DWrapper.PointVecAllocated)

```

I’m guessing that the relationship between “PointVecAllocated” and “PointVec” needs to be made explicit.

---

<div class="post-metadata">

**Author:** ![Josiah\_Slack](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josiah_slack/32/8319_2.png) [@Josiah\_Slack](https://discourse.julialang.org/u/Josiah_Slack)\
**Post date:** [March 8, 2019, 6:14pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/9 "2019-03-08T18:14:55Z")

</div>

I’ve streamlined my example a bit, and am getting results:

```

module BoostWrapper
using CxxWrap
@wrapmodule("libboost_wrap")
function __init__ ()
    @initcxx
end
export Point2D, PointVec, getx, gety,
    Polygon2D, PolygonVec, add_vertex, scale_polygon, get_vertices,
    poly_intersection, intersection_point
end
using Main.BoostWrapper

import Base: getindex, length, convert, iterate, size

iterate(it::PointVec) = length(it) > 0 ? (it[1], 2) : nothing
iterate(it::PointVec, i) = i <= length(it) ? (it[i], i+1) : nothing
length(it::PointVec) = Main.BoostWrapper.size(it)
getindex(it::PointVec, i) = Main.BoostWrapper.at(it, convert(UInt64, i - 1))

eltype(::Type{PointVec}) = Point2D

p1 = Point2D(-10.0, 10.0)
p2 = Point2D(10.0, 10.0)
p3 = Point2D(10.0, -10.0)
p4 = Point2D(-10.0, -10.0)
obstacle = Polygon2D()
add_vertex(obstacle, p1)
add_vertex(obstacle, p2)
add_vertex(obstacle, p3)
add_vertex(obstacle, p4)

pts = get_vertices(obstacle)

for pt in pts
    println("current pt: ", getx(pt), ", ", gety(pt))
end

```

I’m not sure what will happen when I add the other vector type; I may resort to duplicating the iterator code, with unique names for the “at” and “size” methods for the different vectors.

Future me chiming in: I didn’t need to disambiguate “at” and “size” for the different wrapped vectors.

---

<div class="post-metadata">

**Author:** ![barche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barche/32/79_2.png) [@barche](https://discourse.julialang.org/u/barche)\
**Post date:** [March 8, 2019, 6:43pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/10 "2019-03-08T18:43:21Z")

</div>

You can make the vector a parametric type, that should avoid the code duplication. The parametric example should show how to do this.

For what it’s worth, built-in support for std::vector (and others) is on my todo list, but unfortunately my time for working on it has been limited lately.

---

<div class="post-metadata">

**Author:** ![Josiah\_Slack](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josiah_slack/32/8319_2.png) [@Josiah\_Slack](https://discourse.julialang.org/u/Josiah_Slack)\
**Post date:** [March 8, 2019, 6:50pm UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/11 "2019-03-08T18:50:21Z")

</div>

Thanks for the tip - I’ll have a look. For the moment, the code duplication burden isn’t too serious.

---

<div class="post-metadata">

**Author:** ![findmyway](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/findmyway/32/4946_2.png) [@findmyway](https://discourse.julialang.org/u/findmyway)\
**Post date:** [March 9, 2019, 6:15am UTC](https://discourse.julialang.org/t/iterating-over-cxxwrap-ed-vector/21576/12 "2019-03-09T06:15:08Z")

</div>

> [@barche](#):
>
> built-in support for std::vector (and others) is on my todo list,

Can’t wait to see the built-in support ❤ ❤ ❤
