///////////////////////////////////////////////////////////////////////////// // Name: cpp/array_helpers.h // Purpose: some helper functions/classes for array conversion // Author: Mattia Barbon // Modified by: // Created: 27/12/2009 // RCS-ID: $Id: helpers.h 2589 2009-07-01 22:06:13Z mbarbon $ // Copyright: (c) 2009 Mattia Barbon // Licence: This program is free software; you can redistribute it and/or // modify it under the same terms as Perl itself ///////////////////////////////////////////////////////////////////////////// #ifndef __CPP_ARRAY_HELPERS_H #define __CPP_ARRAY_HELPERS_H template int wxPli_av_2_arrayany( pTHX_ SV* avref, typename C::pointer_type array, const F& convertf, const C& allocator ) { AV* av; if( !SvROK( avref ) || ( SvTYPE( (SV*) ( av = (AV*) SvRV( avref ) ) ) != SVt_PVAV ) ) { croak( "the value is not an array reference" ); return 0; } int n = av_len( av ) + 1; typename C::value_type arr = allocator.create( n ); for( int i = 0; i < n; ++i ) { SV* t = *av_fetch( av, i, 0 ); if( !convertf( aTHX_ arr[i], t ) ) { allocator.free( arr ); croak( "invalid conversion for array element" ); return 0; } } allocator.assign( array, arr ); return n; } // value conversion functions class wxPli_convert_sv { public: bool operator()( pTHX_ SV*& dest, SV* src ) const { dest = src; return true; } }; class wxPli_convert_uchar { public: bool operator()( pTHX_ unsigned char& dest, SV* src ) const { dest = (unsigned char) SvUV( src ); return true; } }; class wxPli_convert_int { public: bool operator()( pTHX_ int& dest, SV* src ) const { dest = (int) SvIV( src ); return true; } }; class wxPli_convert_wxstring { public: bool operator()( pTHX_ wxString& dest, SV* src ) const { WXSTRING_INPUT( dest, const char*, src ); return true; } }; // array adapters // C-type arrays template class wxPli_array_allocator { public: typedef CType** pointer_type; typedef CType* value_type; value_type create( size_t n ) const { return new CType[n]; } void assign( pointer_type lv, value_type rv ) const { *lv = rv; } void free( value_type rv ) const { delete[] rv; } }; // wxWidgets' array types template class wxPli_wxarray_allocator { public: typedef A* pointer_type; typedef A& value_type; wxPli_wxarray_allocator( pointer_type lv ) : m_value( lv ) { } value_type create( size_t n ) const { m_value->Alloc( n ); for( size_t i = 0; i < n; ++i ) m_value->Add( V() ); return *m_value; } void assign( pointer_type, value_type ) const { } void free( value_type ) const { } private: A* m_value; }; // adapter for wxVector and std::vector template class wxPli_vector_allocator { public: typedef A* pointer_type; typedef A& value_type; wxPli_vector_allocator( pointer_type lv ) : m_value( lv ) { } value_type create( size_t n ) const { m_value->reserve( n ); for( size_t i = 0; i < n; ++i ) m_value->push_back( V() ); return *m_value; } void assign( pointer_type, value_type ) const { } void free( value_type ) const { } private: A* m_value; }; #endif // __CPP_ARRAY_HELPERS_H