Well then, I am glad that I got the patch ready over the weekend. :-)
The patch has been attached to this e-mail as the file "patch"; it is
the result of running "svn diff" against revision 11556.
I have modified "gecode/kernel/array.hpp" along the lines that we
discussed, and have added a new test to your suite under
"test/array.cpp" to verify that it works as expected.
While I was add it, I added another feature. The patch includes a file
"gecode/iter/wrap-val.hpp" (and a patch to "gecode/iter.hh" to include
this file) which contains an iterator class "WrapVal" that wraps another
iterator and upon dereferencing returns the the result of calling
".val()" on the dereferenced wrapped iterator, as well as a function
"wrap_val" that is a convenience function for constructing a "WrapVal"
(since this causes the template parameters to automatically be inferred).
That might sound complicated, but the point of it is to allow someone to
do the following:
#include <algorithm>
#include <gecode/iter.hh>
#include <iterator>
#include <vector>
...
using namespace Gecode;
using namespace Gecode::Iter;
using namespace std;
...
IntVarArray a;
...
vector<int> v;
copy(wrap_val(a.begin()),wrap_val(a.end()),back_inserter(x));
which has the effect of copying all of the values from the array a into
the vector v, since a.begin() returns an iterator that dereferences to
an IntVar and wrap_val(a.begin()) returns a wrapped iterator that
returns the result of calling .val() on the IntVar.
The basic use case of the iterators is as follows:
IntVarArgs a;
...
for(IntVarArgs::iterator i = a.begin(); i != a.end(); ++i) {
rel(space,*i,IRT_EQ,0); }
Of course, you could more easily do this with rel(space,a,IRT_EQ,0). A
more interesting example is:
IntVarArgs a;
...
for(IntVarArgs::iterator i = a.begin(); i != a.end()-1; ++i) {
rel(space,*i > *(i+1)+2); }
More powerfully, iterators give you the ability to work with STL algorithms:
#include <algorithm>
...
void f(IntVar& v) { ... }
...
IntVarArgs a;
...
std::for_each(a.begin(),a.end(),f);
The iterators returned by a.begin() and a.end() dereference to a
reference to an IntVar/BoolVar (or a view in the case of ViewArray). If
you are interested in iterating over the *values* of the array --- that
is, the value currently assigned to to each variable then you can use
the function wrap_val to wrap these iterators so that dereferencing them
returns the value assigned to the variable. For example, the last two
lines in the following have exactly the same result:
#include <algorithm>
#include <iostream>
...
void f(IntVar& v) { std::cout << v.val() << " "; }
void g(int i) { std::cout << i << " "; }
...
IntVarArgs a;
...
std::for_each(a.begin(),a.end(),f); std::cout << std::endl;
std::for_each(wrap_val(a.begin()),wrap_val(a.end()),g); std::cout
<< std::endl;
Or if you want to copy the values assigned to the variables into a
std::vector:
#include <algorithm>
#include <iterator>
#include <vector>
...
IntVarArray a;
...
std::vector<int> v;
std::copy(wrap_val(a.begin()),wrap_val(a.end()),std::back_inserter(x));
Or if you are interested in computing the sum of the values in the
variables:
#include <numeric>
...
IntVarArray a;
...
int sum = std::accumulate(wrap_val(a.begin()),wrap_val(a.end()),0);
Or alternatively if you are interested in counting the number of zeros
in the variables:
#include <algorithm>
...
IntVarArray a;
...
unsigned int number_of_zeros =
std::count(wrap_val(a.begin()),wrap_val(a.end()),0);
===
Anyway, I hope that this patch can make it into Gecode this week; you
have my official permission to release it under whatever license Gecode
uses.
Let me know if you have any questions! :-)
Cheers,
Gregory Crosswhite
On 01/24/2011 10:54 AM, Christian Schulte wrote:
Christian Schulte<cschulte@...> writes:
Hi again,
There is one thing I forgot to say: we intend to release end of this week
(hopefully). So if your patch arrives until then, it'll be included in the
next version.
Cheers
Christian
_______________________________________________
Gecode users mailing list
[email protected]
https://www.gecode.org/mailman/listinfo/gecode-users
Index: test/iter.cpp
===================================================================
--- test/iter.cpp (revision 0)
+++ test/iter.cpp (revision 0)
@@ -0,0 +1,156 @@
+/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+/*
+ * Main authors:
+ * Gregory Crosswhite <[email protected]>
+ *
+ * Copyright:
+ * Gregory Crosswhite, 2010
+ *
+ * Last modified:
+ * $Date: 2010-04-08 03:35:31 -0700 (Thu, 08 Apr 2010) $ by $Author:
schulte $
+ * $Revision: 10684 $
+ *
+ * This file is part of Gecode, the generic constraint
+ * development environment:
+ * http://www.gecode.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <algorithm>
+#include <gecode/kernel.hh>
+#include <gecode/int.hh>
+#include <gecode/iter.hh>
+#include <gecode/search.hh>
+#include <iterator>
+#include <numeric>
+
+#include "test/test.hh"
+
+namespace Test { namespace Iterator {
+
+ using namespace Gecode;
+ using namespace Gecode::Iter;
+
+ /// %Class for testing WrapVal
+ class WrapVal : public Test::Base {
+ protected:
+ /// Maximum array size
+ static const int n = 8;
+ /// Test space
+ class TestSpace : public Space {
+ public:
+ BoolVarArray a;
+ TestSpace(int n) : a(*this,n,0,1) {
+ branch(*this,a,INT_VAR_NONE,INT_VAL_MIN);
+ }
+ TestSpace(bool share, TestSpace& s) : Space(share,s) {
+ a.update(*this,share,s.a);
+ }
+ virtual Space* copy(bool share) {
+ return new TestSpace(share,*this);
+ }
+ };
+ public:
+ /// Initialize test
+ WrapVal(void) : Test::Base("Iterator::WrapVal") {}
+ /// Perform actual tests
+ bool run(void) {
+ // Search space for the test
+ TestSpace *s = new TestSpace(rand(n));
+ // Search tree for the test
+ DFS<TestSpace> dfs(s); delete s;
+ // Run the iterator test
+ while((s = dfs.next())) {
+ {
+ BoolVarArray& a = s->a;
+ std::vector<int> v;
+ copy(wrap_val(a.begin()),wrap_val(a.end()),std::back_inserter(v));
+ if(v.size() != (unsigned int)a.size()) {
+ if(opt.log) olog << "FAILED: Wrapped iterator distance did not
match array size" << std::endl;
+ return false;
+ }
+ for(size_t i = 0u; i < v.size(); ++i) {
+ if(v[i] != a[i].val()) {
+ if(opt.log) olog << "FAILED: Dereferencing the wrapped iterator
obtained the wrong value" << std::endl;
+ return false;
+ }
+ }
+ const int
+ correct_weight = std::accumulate(v.begin(),v.end(),0),
+ counted_weight =
std::count(wrap_val(a.begin()),wrap_val(a.end()),1),
+ accumulated_weight =
std::accumulate(wrap_val(a.begin()),wrap_val(a.end()),0);
+ if(correct_weight != counted_weight) {
+ if(opt.log)
+ olog << "FAILED: std::count obtained the wrong value"
+ << " (" << correct_weight << " != " << counted_weight << "
) "
+ << std::endl;
+ return false;
+ }
+ if(correct_weight != accumulated_weight) {
+ if(opt.log)
+ olog << "FAILED: std::accumulate obtained the wrong value"
+ << " (" << correct_weight << " != " << accumulated_weight
<< " ) "
+ << std::endl;
+ return false;
+ }
+ }
+ {
+ const BoolVarArray& a = s->a;
+ std::vector<int> v;
+ copy(wrap_val(a.begin()),wrap_val(a.end()),std::back_inserter(v));
+ if(v.size() != (unsigned int)a.size()) {
+ if(opt.log) olog << "FAILED: Wrapped (const) iterator distance
did not match array size" << std::endl;
+ return false;
+ }
+ for(size_t i = 0u; i < v.size(); ++i) {
+ if(v[i] != a[i].val()) {
+ if(opt.log) olog << "FAILED: Dereferencing the wrapped (const)
iterator obtained the wrong value" << std::endl;
+ return false;
+ }
+ }
+ const int
+ correct_weight = std::accumulate(v.begin(),v.end(),0),
+ counted_weight =
std::count(wrap_val(a.begin()),wrap_val(a.end()),1),
+ accumulated_weight =
std::accumulate(wrap_val(a.begin()),wrap_val(a.end()),0);
+ if(correct_weight != counted_weight) {
+ if(opt.log)
+ olog << "FAILED: std::count obtained the wrong value (const
case) "
+ << " (" << correct_weight << " != " << counted_weight << "
) "
+ << std::endl;
+ return false;
+ }
+ if(correct_weight != accumulated_weight) {
+ if(opt.log)
+ olog << "FAILED: std::accumulate obtained the wrong value
(const case) "
+ << " (" << correct_weight << " != " << accumulated_weight
<< " ) "
+ << std::endl;
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ } wrapValTest;
+
+} }
+
+// STATISTICS: test-array
Index: test/array.cpp
===================================================================
--- test/array.cpp (revision 0)
+++ test/array.cpp (revision 0)
@@ -0,0 +1,255 @@
+/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+/*
+ * Main authors:
+ * Gregory Crosswhite <[email protected]>
+ *
+ * Copyright:
+ * Gregory Crosswhite, 2010
+ *
+ * Last modified:
+ * $Date: 2010-04-08 03:35:31 -0700 (Thu, 08 Apr 2010) $ by $Author:
schulte $
+ * $Revision: 10684 $
+ *
+ * This file is part of Gecode, the generic constraint
+ * development environment:
+ * http://www.gecode.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <gecode/kernel.hh>
+#include <gecode/int.hh>
+
+#include "test/test.hh"
+
+/// Check the test result and handle failed test
+#define CHECK_TEST(T,M) \
+if (opt.log) \
+ olog << ind(3) << "Check: " << (M) << std::endl; \
+if (!(T)) { \
+ problem = (M); goto failed; \
+}
+
+/// Start new test
+#define START_TEST(T) \
+ if (opt.log) { \
+ olog.str(""); \
+ olog << ind(2) << "Testing: " << (T) << std::endl; \
+ } \
+ test = (T);
+
+namespace Test { namespace Array { namespace Iterator {
+
+ /// Test name prefix
+ static const std::string prefix("Array::Iterator::");
+
+ /// %Base class for testing iterators
+ class Iterator : public Test::Base {
+ protected:
+ /// Maximum array size
+ static const int n = 16;
+ /// Initialize test
+ Iterator(const std::string& name) : Test::Base(prefix + name) {}
+ /// Perform actual tests
+ template<class Array> bool runTestForArray(Array& a) {
+ // Test/problem information.
+ const char* test = "NONE";
+ const char* problem = "NONE";
+ // Constant reference to the array
+ const Array& const_a = a;
+
+ START_TEST("Iteration");
+ {
+ typedef typename Array::reference reference;
+ typedef typename Array::pointer pointer;
+ typedef typename Array::iterator iterator;
+ const iterator begin = a.begin(), end = a.end();
+ CHECK_TEST(end-begin==a.size(),"Distance != size");
+ int index = 0;
+ iterator iter = begin;
+ for(; iter != end; ++iter, ++index) {
+ const reference ref = *iter;
+ const pointer ptr = &ref;
+ CHECK_TEST(ptr==&a[index],"Iterator points to the wrong element
(going forward)");
+ }
+ CHECK_TEST(index==a.size(),"Iteration covered the wrong number of
elements (going forward)");
+ for(; iter != begin; --iter, --index) {
+ const reference ref = *(iter-1);
+ const pointer ptr = &ref;
+ CHECK_TEST(ptr==&a[index-1],"Iterator points to the wrong element
(going backwards)");
+ }
+ CHECK_TEST(index==0,"Iteration covered the wrong number of elements
(going backward)");
+ }
+ START_TEST("Read-only iteration");
+ {
+ typedef typename Array::const_reference reference;
+ typedef typename Array::const_pointer pointer;
+ typedef typename Array::const_iterator iterator;
+ const iterator begin = const_a.begin(), end = const_a.end();
+ CHECK_TEST(end-begin==const_a.size(),"Distance != size");
+ int index = 0;
+ iterator iter = begin;
+ for(; iter != end; ++iter, ++index) {
+ const reference ref = *iter;
+ const pointer ptr = &ref;
+ CHECK_TEST(ptr==&const_a[index],"Iterator points to the wrong
element (going forward)");
+ }
+ CHECK_TEST(index==const_a.size(),"Iteration covered the wrong number
of elements (going forward)");
+ for(; iter != begin; --iter, --index) {
+ const reference ref = *(iter-1);
+ const pointer ptr = &ref;
+ CHECK_TEST(ptr==&const_a[index-1],"Iterator points to the wrong
element (going backwards)");
+ }
+ CHECK_TEST(index==0,"Iteration covered the wrong number of elements
(going backward)");
+ }
+
+ START_TEST("Reverse iteration");
+ {
+ typedef typename Array::reference reference;
+ typedef typename Array::pointer pointer;
+ typedef typename Array::reverse_iterator iterator;
+ const iterator begin = a.rbegin(), end = a.rend();
+ CHECK_TEST(end-begin==a.size(),"Distance != size");
+ int index = a.size();
+ iterator iter = begin;
+ for(; iter != end; ++iter, --index) {
+ const reference ref = *iter;
+ const pointer ptr = &ref;
+ CHECK_TEST(ptr==&a[index-1],"Iterator points to the wrong element
(going forward)");
+ }
+ CHECK_TEST(index==0,"Iteration covered the wrong number of elements
(going forward)");
+ for(; iter != begin; --iter, ++index) {
+ const reference ref = *(iter-1);
+ const pointer ptr = &ref;
+ CHECK_TEST(ptr==&a[index],"Iterator points to the wrong element
(going backwards)");
+ }
+ CHECK_TEST(index==a.size(),"Iteration covered the wrong number of
elements (going backward)");
+ }
+
+ START_TEST("Reverse read-only iteration");
+ {
+ typedef typename Array::const_reference reference;
+ typedef typename Array::const_pointer pointer;
+ typedef typename Array::const_reverse_iterator iterator;
+ const iterator begin = const_a.rbegin(), end = const_a.rend();
+ CHECK_TEST(end-begin==const_a.size(),"Distance != size");
+ int index = a.size();
+ iterator iter = begin;
+ for(; iter != end; ++iter, --index) {
+ const reference ref = *iter;
+ const pointer ptr = &ref;
+ CHECK_TEST(ptr==&const_a[index-1],"Iterator points to the wrong
element (going forward)");
+ }
+ CHECK_TEST(index==0,"Iteration covered the wrong number of elements
(going forward)");
+ for(; iter != begin; --iter, ++index) {
+ const reference ref = *(iter-1);
+ const pointer ptr = &ref;
+ CHECK_TEST(ptr==&const_a[index],"Iterator points to the wrong
element (going backwards)");
+ }
+ CHECK_TEST(index==a.size(),"Iteration covered the wrong number of
elements (going backward)");
+ }
+
+ return true;
+ failed:
+ if (opt.log)
+ olog << "FAILURE" << std::endl
+ << ind(1) << "Test: " << test << std::endl
+ << ind(1) << "Problem: " << problem << std::endl;
+ return false;
+ }
+ };
+
+ /// Test space
+ class TestSpace : public Gecode::Space {
+ public:
+ TestSpace(void) : Space() {}
+ TestSpace(bool share, TestSpace& s) : Space(share,s) {}
+ virtual Space* copy(bool share) {
+ return new TestSpace(share,*this);
+ }
+ };
+
+ /// %Class for testing the VarArray iterator
+ class VarArrayIterator : public Iterator {
+ protected:
+ /// Maximum array size
+ static const int n = 16;
+ /// Array type being tested
+ typedef Gecode::VarArray<Gecode::IntVar> Array;
+ public:
+ /// Initialize test
+ VarArrayIterator(void) : Iterator("VarArray") {}
+ /// Perform actual tests
+ bool run(void) {
+ // Space for the test
+ TestSpace s;
+ // VarArray for the test
+ Array a(s,rand(n));
+ // Run the iterator test
+ return runTestForArray(a);
+ }
+ } varArrayIteratorTest;
+
+ /// %Class for testing the VarArgs iterator
+ class VarArgsIterator : public Iterator {
+ protected:
+ /// Maximum array size
+ static const int n = 16;
+ /// Array type being tested
+ typedef Gecode::ArgArrayBase<int> Array;
+ public:
+ /// Initialize test
+ VarArgsIterator(void) : Iterator("VarArgs") {}
+ /// Perform actual tests
+ bool run(void) {
+ // Space for the test
+ TestSpace s;
+ // VarArray for the test
+ Array a(rand(n));
+ // Run the iterator test
+ return runTestForArray(a);
+ }
+ } varArgsIteratorTest;
+
+ /// %Class for testing the ViewArray iterator
+ class ViewArrayIterator : public Iterator {
+ protected:
+ /// Maximum array size
+ static const int n = 16;
+ /// Array type being tested
+ typedef Gecode::ViewArray<Gecode::IntVar> Array;
+ public:
+ /// Initialize test
+ ViewArrayIterator(void) : Iterator("ViewArray") {}
+ /// Perform actual tests
+ bool run(void) {
+ // Space for the test
+ TestSpace s;
+ // VarArray for the test
+ Array a(s,rand(n));
+ // Run the iterator test
+ return runTestForArray(a);
+ }
+ } viewArrayIteratorTest;
+
+} } }
+
+// STATISTICS: test-array
Index: Makefile.in
===================================================================
--- Makefile.in (revision 11556)
+++ Makefile.in (working copy)
@@ -974,12 +974,16 @@
SEARCHTESTSRC0 = \
test/search.cpp
+ARRAYTESTSRC0 = \
+ test/array.cpp test/iter.cpp
+
TESTSRC0 = test/test.cpp test/afc.cpp
TESTSRC = \
$(TESTSRC0) $(INTTESTSRC0) $(SETTESTSRC0) \
$(SCHEDULINGTESTSRC0) $(GRAPHTESTSRC0) \
- $(BRANCHTESTSRC0) $(SEARCHTESTSRC0)
+ $(BRANCHTESTSRC0) $(SEARCHTESTSRC0) \
+ $(ARRAYTESTSRC0)
TESTHDR0 = \
test.hh test.hpp int.hh int.hpp set.hh set.hpp \
@@ -989,6 +993,7 @@
$(SCHEDULINGTESTOBJ) $(GRAPHTESTOBJ) \
$(BRANCHTESTSRC0:%.cpp=%$(OBJSUFFIX)) \
$(SEARCHTESTSRC0:%.cpp=%$(OBJSUFFIX)) \
+ $(ARRAYTESTSRC0:%.cpp=%$(OBJSUFFIX)) \
$(TESTSRC0:%.cpp=%$(OBJSUFFIX))
TESTSBJ = $(TESTOBJ:%$(OBJSUFFIX)=%$(SBJSUFFIX))
TESTEXE = test/test$(EXESUFFIX)
Index: gecode/kernel/array.hpp
===================================================================
--- gecode/kernel/array.hpp (revision 11556)
+++ gecode/kernel/array.hpp (working copy)
@@ -39,6 +39,7 @@
#include <cstdarg>
#include <iostream>
+#include <iterator>
#include <sstream>
namespace Gecode {
@@ -84,6 +85,29 @@
/// Array of variables
Var* x;
public:
+ /// \name Associated types
+ //@{
+ /// Type of the variable stored in this array
+ typedef Var value_type;
+ /// Type of a reference to the value type
+ typedef Var& reference;
+ /// Type of a constant reference to the value type
+ typedef const Var& const_reference;
+ /// Type of a pointer to the value type
+ typedef Var* pointer;
+ /// Type of a read-only pointer to the value type
+ typedef const Var* const_pointer;
+ /// Type of the iterator used to iterate through this array's elements
+ typedef Var* iterator;
+ /// Type of the iterator used to iterate read-only through this array's
elements
+ typedef const Var* const_iterator;
+ /// Type of the iterator used to iterate backwards through this array's
elements
+ typedef std::reverse_iterator<Var*> reverse_iterator;
+ /// Type of the iterator used to iterate backwards and read-only through
this array's elements
+ typedef std::reverse_iterator<const Var*> const_reverse_iterator;
+ //@}
+
+ //@{
/// \name Constructors and initialization
//@{
/// Default constructor (array of size 0)
@@ -119,6 +143,26 @@
slice(int start, int inc=1, int n=-1);
//@}
+ /// \name Array iteration
+ //@{
+ /// Return an iterator at the beginning of the array
+ iterator begin();
+ /// Return a read-only iterator at the beginning of the array
+ const_iterator begin() const;
+ /// Return an iterator past the end of the array
+ iterator end();
+ /// Return a read-only iterator past the end of the array
+ const_iterator end() const;
+ /// Return a reverse iterator at the end of the array
+ reverse_iterator rbegin();
+ /// Return a reverse and read-only iterator at the end of the array
+ const_reverse_iterator rbegin() const;
+ /// Return a reverse iterator past the beginning of the array
+ reverse_iterator rend();
+ /// Return a reverse and read-only iterator past the beginning of the array
+ const_reverse_iterator rend() const;
+ //@}
+
/// Test if all variables are assigned
bool assigned(void) const;
@@ -197,6 +241,28 @@
/// Sort \a n views \a x according to \a ViewLess
static void sort(View* x, int n);
public:
+ /// \name Associated types
+ //@{
+ /// Type of the view stored in this array
+ typedef View value_type;
+ /// Type of a reference to the value type
+ typedef View& reference;
+ /// Type of a constant reference to the value type
+ typedef const View& const_reference;
+ /// Type of a pointer to the value type
+ typedef View* pointer;
+ /// Type of a read-only pointer to the value type
+ typedef const View* const_pointer;
+ /// Type of the iterator used to iterate through this array's elements
+ typedef View* iterator;
+ /// Type of the iterator used to iterate read-only through this array's
elements
+ typedef const View* const_iterator;
+ /// Type of the iterator used to iterate backwards through this array's
elements
+ typedef std::reverse_iterator<View*> reverse_iterator;
+ /// Type of the iterator used to iterate backwards and read-only through
this array's elements
+ typedef std::reverse_iterator<const View*> const_reverse_iterator;
+ //@}
+
/// \name Constructors and initialization
//@{
/// Default constructor (array of size 0)
@@ -245,6 +311,26 @@
const View& operator [](int i) const;
//@}
+ /// \name Array iteration
+ //@{
+ /// Return an iterator at the beginning of the array
+ iterator begin();
+ /// Return a read-only iterator at the beginning of the array
+ const_iterator begin() const;
+ /// Return an iterator past the end of the array
+ iterator end();
+ /// Return a read-only iterator past the end of the array
+ const_iterator end() const;
+ /// Return a reverse iterator at the end of the array
+ reverse_iterator rbegin();
+ /// Return a reverse and read-only iterator at the end of the array
+ const_reverse_iterator rbegin() const;
+ /// Return a reverse iterator past the beginning of the array
+ reverse_iterator rend();
+ /// Return a reverse and read-only iterator past the beginning of the array
+ const_reverse_iterator rend() const;
+ //@}
+
/// \name Dependencies
//@{
/**
@@ -441,6 +527,28 @@
template<class A>
A slice(int start, int inc=1, int n=-1);
public:
+ /// \name Associated types
+ //@{
+ /// Type of the view stored in this array
+ typedef T value_type;
+ /// Type of a reference to the value type
+ typedef T& reference;
+ /// Type of a constant reference to the value type
+ typedef const T& const_reference;
+ /// Type of a pointer to the value type
+ typedef T* pointer;
+ /// Type of a read-only pointer to the value type
+ typedef const T* const_pointer;
+ /// Type of the iterator used to iterate through this array's elements
+ typedef T* iterator;
+ /// Type of the iterator used to iterate read-only through this array's
elements
+ typedef const T* const_iterator;
+ /// Type of the iterator used to iterate backwards through this array's
elements
+ typedef std::reverse_iterator<T*> reverse_iterator;
+ /// Type of the iterator used to iterate backwards and read-only through
this array's elements
+ typedef std::reverse_iterator<const T*> const_reverse_iterator;
+ //@}
+
/// \name Constructors and initialization
//@{
/// Allocate empty array
@@ -467,6 +575,26 @@
const T& operator [](int i) const;
//@}
+ /// \name Array iteration
+ //@{
+ /// Return an iterator at the beginning of the array
+ iterator begin();
+ /// Return a read-only iterator at the beginning of the array
+ const_iterator begin() const;
+ /// Return an iterator past the end of the array
+ iterator end();
+ /// Return a read-only iterator past the end of the array
+ const_iterator end() const;
+ /// Return a reverse iterator at the end of the array
+ reverse_iterator rbegin();
+ /// Return a reverse and read-only iterator at the end of the array
+ const_reverse_iterator rbegin() const;
+ /// Return a reverse iterator past the beginning of the array
+ reverse_iterator rend();
+ /// Return a reverse and read-only iterator past the beginning of the array
+ const_reverse_iterator rend() const;
+ //@}
+
/// \name Destructor
//@{
/// Destructor
@@ -848,6 +976,54 @@
}
template<class Var>
+ forceinline typename VarArray<Var>::iterator
+ VarArray<Var>::begin() {
+ return x;
+ }
+
+ template<class Var>
+ forceinline typename VarArray<Var>::const_iterator
+ VarArray<Var>::begin() const {
+ return x;
+ }
+
+ template<class Var>
+ forceinline typename VarArray<Var>::iterator
+ VarArray<Var>::end() {
+ return x+n;
+ }
+
+ template<class Var>
+ forceinline typename VarArray<Var>::const_iterator
+ VarArray<Var>::end() const {
+ return x+n;
+ }
+
+ template<class Var>
+ forceinline typename VarArray<Var>::reverse_iterator
+ VarArray<Var>::rbegin() {
+ return reverse_iterator(x+n);
+ }
+
+ template<class Var>
+ forceinline typename VarArray<Var>::const_reverse_iterator
+ VarArray<Var>::rbegin() const {
+ return const_reverse_iterator(x+n);
+ }
+
+ template<class Var>
+ forceinline typename VarArray<Var>::reverse_iterator
+ VarArray<Var>::rend() {
+ return reverse_iterator(x);
+ }
+
+ template<class Var>
+ forceinline typename VarArray<Var>::const_reverse_iterator
+ VarArray<Var>::rend() const {
+ return const_reverse_iterator(x);
+ }
+
+ template<class Var>
forceinline void
VarArray<Var>::update(Space& home, bool share, VarArray<Var>& a) {
n = a.n;
@@ -1000,6 +1176,54 @@
}
template<class View>
+ forceinline typename ViewArray<View>::iterator
+ ViewArray<View>::begin() {
+ return x;
+ }
+
+ template<class View>
+ forceinline typename ViewArray<View>::const_iterator
+ ViewArray<View>::begin() const {
+ return x;
+ }
+
+ template<class View>
+ forceinline typename ViewArray<View>::iterator
+ ViewArray<View>::end() {
+ return x+n;
+ }
+
+ template<class View>
+ forceinline typename ViewArray<View>::const_iterator
+ ViewArray<View>::end() const {
+ return x+n;
+ }
+
+ template<class View>
+ forceinline typename ViewArray<View>::reverse_iterator
+ ViewArray<View>::rbegin() {
+ return reverse_iterator(x+n);
+ }
+
+ template<class View>
+ forceinline typename ViewArray<View>::const_reverse_iterator
+ ViewArray<View>::rbegin() const {
+ return const_reverse_iterator(x+n);
+ }
+
+ template<class View>
+ forceinline typename ViewArray<View>::reverse_iterator
+ ViewArray<View>::rend() {
+ return reverse_iterator(x);
+ }
+
+ template<class View>
+ forceinline typename ViewArray<View>::const_reverse_iterator
+ ViewArray<View>::rend() const {
+ return const_reverse_iterator(x);
+ }
+
+ template<class View>
forceinline void
ViewArray<View>::move_fst(int i) {
x[i]=x[0]; x++; n--;
@@ -1384,6 +1608,54 @@
return a[i];
}
+ template<class T>
+ forceinline typename ArgArrayBase<T>::iterator
+ ArgArrayBase<T>::begin() {
+ return a;
+ }
+
+ template<class T>
+ forceinline typename ArgArrayBase<T>::const_iterator
+ ArgArrayBase<T>::begin() const {
+ return a;
+ }
+
+ template<class T>
+ forceinline typename ArgArrayBase<T>::iterator
+ ArgArrayBase<T>::end() {
+ return a+n;
+ }
+
+ template<class T>
+ forceinline typename ArgArrayBase<T>::const_iterator
+ ArgArrayBase<T>::end() const {
+ return a+n;
+ }
+
+ template<class T>
+ forceinline typename ArgArrayBase<T>::reverse_iterator
+ ArgArrayBase<T>::rbegin() {
+ return reverse_iterator(a+n);
+ }
+
+ template<class T>
+ forceinline typename ArgArrayBase<T>::const_reverse_iterator
+ ArgArrayBase<T>::rbegin() const {
+ return const_reverse_iterator(a+n);
+ }
+
+ template<class T>
+ forceinline typename ArgArrayBase<T>::reverse_iterator
+ ArgArrayBase<T>::rend() {
+ return reverse_iterator(a);
+ }
+
+ template<class T>
+ forceinline typename ArgArrayBase<T>::const_reverse_iterator
+ ArgArrayBase<T>::rend() const {
+ return const_reverse_iterator(a);
+ }
+
template<class T> template<class A>
A
ArgArrayBase<T>::slice(int start, int inc, int maxN) {
Index: gecode/iter.hh
===================================================================
--- gecode/iter.hh (revision 11556)
+++ gecode/iter.hh (working copy)
@@ -88,6 +88,8 @@
#include <gecode/iter/ranges-size.hpp>
+#include <gecode/iter/wrap-val.hpp>
+
#endif
// STATISTICS: iter-any
Index: gecode/iter/wrap-val.hpp
===================================================================
--- gecode/iter/wrap-val.hpp (revision 0)
+++ gecode/iter/wrap-val.hpp (revision 0)
@@ -0,0 +1,106 @@
+/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+/*
+ * Main authors:
+ * Gregory Crosswhite <[email protected]>
+ *
+ * Copyright:
+ * Gregory Crosswhite, 2010
+ *
+ * Last modified:
+ * $Date: 2010-07-28 08:35:33 -0700 (Wed, 28 Jul 2010) $ by $Author:
schulte $
+ * $Revision: 11294 $
+ *
+ * This file is part of Gecode, the generic constraint
+ * development environment:
+ * http://www.gecode.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <iterator>
+
+namespace Gecode { namespace Iter {
+
+ /**
+ * \brief Wrapping iterator that dereferences to the value of the wrapped
iterator
+ */
+ template<class I>
+ class WrapVal : public std::iterator
+ <typename std::iterator_traits<I>::iterator_category
+ ,int
+ ,typename std::iterator_traits<I>::difference_type
+ >
+ {
+ protected:
+ /// Wrapped iterator
+ I i;
+ public:
+ typedef typename std::iterator_traits<I>::difference_type difference_type;
+ /// \name Constructors and initialization
+ //@{
+ /// Default constructor
+ WrapVal(void) { };
+ /// Initialize with wrapped iterator
+ WrapVal(const I i) : i(i) { };
+ //@}
+
+ /// \name Iteration control
+ //@{
+ /// Move iterator to the next element
+ void operator ++(void) { ++i; }
+ /// Move iterator to the previous element
+ void operator --(void) { --i; };
+ /// Advance the iterator
+ void operator +=(const difference_type n) { i += n; }
+ /// Retrograde the iterator
+ void operator -=(const difference_type n) { i -= n; }
+ /// Return advanced iterator
+ WrapVal operator +(const difference_type n) const { return WrapVal(i+n); }
+ /// Return retrograded iterator
+ WrapVal operator -(const difference_type n) const { return WrapVal(i-n); }
+ //@}
+
+ /// \name Iteration distance
+ //@{
+ /// Return distance between two iterators
+ difference_type operator -(const WrapVal& o) const { return i-o.i; }
+ //@}
+
+ /// \name Comparison operators
+ //@{
+ int operator ==(const WrapVal o) const { return i == o.i; }
+ int operator !=(const WrapVal o) const { return i != o.i; }
+ int operator >=(const WrapVal o) const { return i >= o.i; }
+ int operator <=(const WrapVal o) const { return i <= o.i; }
+ int operator > (const WrapVal o) const { return i > o.i; }
+ int operator < (const WrapVal o) const { return i < o.i; }
+ //@}
+
+ /// \name Dereference
+ //@{
+ /// Extract the value of the underyling iterator
+ int operator *(void) const { return i->val(); };
+ //@}
+ };
+
+ template<class I> WrapVal<I> wrap_val(const I i) { return WrapVal<I>(i); }
+
+} }
_______________________________________________
Gecode users mailing list
[email protected]
https://www.gecode.org/mailman/listinfo/gecode-users