PHP std::vector wrappers overhaul modelling on Java std_vector.i. Work around empty rename warning problem. Add capacity and reserve(). Remove need for specialize_std_vector macro.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11550 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2009-08-13 22:07:34 +00:00
commit d2316a8189
2 changed files with 90 additions and 115 deletions

View file

@ -1,6 +1,10 @@
Version 1.3.40 (in progress) Version 1.3.40 (in progress)
============================ ============================
2009-08-13: wsfulton
[PHP] std::vector wrappers overhaul. They no longer require the
specialize_std_vector() macro. Added wrappers for capacity() and reserve().
2009-08-13: wsfulton 2009-08-13: wsfulton
[PHP] Add const reference typemaps. const reference primitive types are [PHP] Add const reference typemaps. const reference primitive types are
now passed by value rather than pointer like the other target languages. now passed by value rather than pointer like the other target languages.

View file

@ -3,132 +3,103 @@
* of SWIG, and the README file for authors - http://www.swig.org/release.html. * of SWIG, and the README file for authors - http://www.swig.org/release.html.
* *
* std_vector.i * std_vector.i
*
* SWIG typemaps for std::vector types
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
%include <std_common.i> %include <std_common.i>
// ------------------------------------------------------------------------
// std::vector
//
// The aim of all that follows would be to integrate std::vector with
// PHP as much as possible, namely, to allow the user to pass and
// be returned PHP lists.
// const declarations are used to guess the intent of the function being
// exported; therefore, the following rationale is applied:
//
// -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*):
// the parameter being read-only, either a PHP sequence or a
// previously wrapped std::vector<T> can be passed.
// -- f(std::vector<T>&), f(std::vector<T>*):
// the parameter must be modified; therefore, only a wrapped std::vector
// can be passed.
// -- std::vector<T> f():
// the vector is returned by copy; therefore, a PHP sequence of T:s
// is returned which is most easily used in other PHP functions
// -- std::vector<T>& f(), std::vector<T>* f(), const std::vector<T>& f(),
// const std::vector<T>* f():
// the vector is returned by reference; therefore, a wrapped std::vector
// is returned
// ------------------------------------------------------------------------
%{ %{
#include <vector> #include <vector>
#include <algorithm>
#include <stdexcept> #include <stdexcept>
%} %}
// exported class
namespace std { namespace std {
template<class T> class vector {
// add generic typemaps here
public:
vector(unsigned int size = 0);
unsigned int size() const;
%rename(is_empty) empty;
bool empty() const;
void clear();
%rename(push) push_back;
void push_back(const T& x);
%extend {
T pop() throw (std::out_of_range) {
if (self->size() == 0)
throw std::out_of_range("pop from empty vector");
T x = self->back();
self->pop_back();
return x;
}
T& get(int i) throw (std::out_of_range) {
int size = int(self->size());
if (i>=0 && i<size)
return (*self)[i];
else
throw std::out_of_range("vector index out of range");
}
void set(int i, const T& x) throw (std::out_of_range) {
int size = int(self->size());
if (i>=0 && i<size)
(*self)[i] = x;
else
throw std::out_of_range("vector index out of range");
}
}
};
template<class T> class vector {
public:
typedef size_t size_type;
typedef T value_type;
typedef const value_type& const_reference;
vector();
vector(size_type n);
size_type size() const;
size_type capacity() const;
void reserve(size_type n);
void clear();
%rename(push) push_back;
void push_back(const value_type& x);
%extend {
bool is_empty() const {
return $self->empty();
}
T pop() throw (std::out_of_range) {
if (self->size() == 0)
throw std::out_of_range("pop from empty vector");
T x = self->back();
self->pop_back();
return x;
}
const_reference get(int i) throw (std::out_of_range) {
int size = int(self->size());
if (i>=0 && i<size)
return (*self)[i];
else
throw std::out_of_range("vector index out of range");
}
void set(int i, const value_type& val) throw (std::out_of_range) {
int size = int(self->size());
if (i>=0 && i<size)
(*self)[i] = val;
else
throw std::out_of_range("vector index out of range");
}
}
};
// specializations for built-ins // bool specialization
template<> class vector<bool> {
%define specialize_std_vector(T) public:
template<> class vector<T> { typedef size_t size_type;
// add specialized typemaps here typedef bool value_type;
public: typedef bool const_reference;
vector(unsigned int size = 0); vector();
unsigned int size() const; vector(size_type n);
%rename(is_empty) empty; size_type size() const;
bool empty() const; size_type capacity() const;
void clear(); void reserve(size_type n);
%rename(push) push_back; void clear();
void push_back(T x); %rename(push) push_back;
%extend { void push_back(const value_type& x);
T pop() throw (std::out_of_range) { %extend {
if (self->size() == 0) bool is_empty() const {
throw std::out_of_range("pop from empty vector"); return $self->empty();
T x = self->back(); }
self->pop_back(); bool pop() throw (std::out_of_range) {
return x; if (self->size() == 0)
} throw std::out_of_range("pop from empty vector");
T get(int i) throw (std::out_of_range) { bool x = self->back();
int size = int(self->size()); self->pop_back();
if (i>=0 && i<size) return x;
return (*self)[i]; }
else const_reference get(int i) throw (std::out_of_range) {
throw std::out_of_range("vector index out of range"); int size = int(self->size());
} if (i>=0 && i<size)
void set(int i, T x) throw (std::out_of_range) { return (*self)[i];
int size = int(self->size()); else
if (i>=0 && i<size) throw std::out_of_range("vector index out of range");
(*self)[i] = x; }
else void set(int i, const value_type& val) throw (std::out_of_range) {
throw std::out_of_range("vector index out of range"); int size = int(self->size());
} if (i>=0 && i<size)
} (*self)[i] = val;
}; else
%enddef throw std::out_of_range("vector index out of range");
}
specialize_std_vector(bool); }
specialize_std_vector(char); };
specialize_std_vector(int);
specialize_std_vector(short);
specialize_std_vector(long);
specialize_std_vector(unsigned char);
specialize_std_vector(unsigned int);
specialize_std_vector(unsigned short);
specialize_std_vector(unsigned long);
specialize_std_vector(float);
specialize_std_vector(double);
} }
%define specialize_std_vector(T)
#warning "specialize_std_vector - specialization for type T no longer needed"
%enddef