Difference between revisions of "Helper Class Implementations"

From Apache OpenOffice Wiki
Jump to: navigation, search
 
m (C++ Sequence to/from STL container converter)
Line 37: Line 37:
  
 
From time to time, one needs to convert from a uno::Sequence to and
 
From time to time, one needs to convert from a uno::Sequence to and
fro a STL container or a plain old array. If you need to copy anyway
+
from a STL container or a plain old array. If you need to copy anyway
 
(instead of somehow facading the uno::Sequence with something that
 
(instead of somehow facading the uno::Sequence with something that
 
masquerades it as an STL container), use these function templates
 
masquerades it as an STL container), use these function templates

Revision as of 07:51, 16 November 2005

Started by Frank Schönheit on mailing list as HOTD.

Every time I'm writing a piece of code, and need some helper class which I assume is already implemented somewhere (since my requirement sounds quite generic), I can't help but get the impression that we have hundreds of helper implementations, of which 95% are unknown to 95% of us developers.

That is, comphelper and unotools (my two favourites) alone contain more than 100 files, not to mention cppuhelper, salhelper, and (for higher levels) tools & svtools (plus maybe more).

The most files therein are completely unknown to me (side note: though they are young enough that the interface they implement should have been announced in interface-announce@openoffice.org :( ).

Maybe it's only me, but somehow I believe that a lot of us don't even know the goodies which hide in the various *helper places, and thus either unnecessarily re-implement them, or simply produce code which could have been more elegant, and/or more robust, and/or easier to maintain, and/or easier to read, ... (continue at will).

What I would like to suggest is some kind of "Helper of the Day" initiative. People who know a certain piece of (helper) code in one of the above-mentioned projects should introduce this piece to others, shortly saying what it is (and perhaps what it is _not_) good for. Ideally, this means just copying the code's documentation into an email, less ideally, this means writing this documentation first.

Those mails could, in irregular order, be posted to some list (probably dev@ooo, or interface-announce@ooo, or ?). If we give them a tag (say: [HOTD] :), and a good summary, this could create an informal pool of information.

C++ Sequence to/from STL container converter

--Thorsten Behrens

From time to time, one needs to convert from a uno::Sequence to and from a STL container or a plain old array. If you need to copy anyway (instead of somehow facading the uno::Sequence with something that masquerades it as an STL container), use these function templates (from comphelper/sequence.hxx):

	/** Copy from a plain C/C++ array into a Sequence.

    	@tpl SrcType
        Array element type. Must be assignable to DstType

        @tpl DstType
        Sequence element type. Must be assignable from SrcType

    	@param i_pArray
        Valid pointer to at least num elements of type SrcType

        @param nNum
        Number of array elements to copy

        @return the resulting Sequence

        @attention when copying from e.g. a double array to a
        Sequence<int>, no proper rounding will be performed, but the
        values will be truncated. There's currently no measure to
        prevent or detect precision loss, overflow or truncation.
     */
    template < typename DstType, typename SrcType > 
    ::com::sun::star::uno::Sequence< DstType > arrayToSequence( const SrcType* i_pArray, sal_Int32 nNum )
    {
        ::com::sun::star::uno::Sequence< DstType > result( nNum );
        ::std::copy( i_pArray, i_pArray+nNum, result.getArray() );
        return result;
    }

	//-------------------------------------------------------------------------
	/** Copy from a Sequence into a plain C/C++ array

        @tpl SrcType
        Sequence element type. Must be assignable to DstType

    	@tpl DstType
        Array element type. Must be assignable from SrcType

    	@param io_pArray
        Valid pointer to at least i_Sequence.getLength() elements of
        type DstType

        @param i_Sequence
        Reference to a Sequence of SrcType elements

        @return a pointer to the array

        @attention when copying from e.g. a Sequence<double> to an int
        array, no proper rounding will be performed, but the values
        will be truncated. There's currently no measure to prevent or
        detect precision loss, overflow or truncation.
     */
    template < typename DstType, typename SrcType > 
    DstType* sequenceToArray( DstType* io_pArray, const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence )
    {
        ::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), io_pArray );
        return io_pArray;
    }

	//-------------------------------------------------------------------------
	/** Copy from a container into a Sequence

    	@tpl SrcType
        Container type. This type must fulfill the STL container
        concept, in particular, the size(), begin() and end() methods
        must be available and have the usual semantics.

        @tpl DstType
        Sequence element type. Must be assignable from SrcType's
        elements

    	@param i_Container
        Reference to the input contain with elements of type SrcType

        @return the generated Sequence

        @attention this function always performs a copy. Furthermore,
        when copying from e.g. a vector<double> to a Sequence<int>, no
        proper rounding will be performed, but the values will be
        truncated. There's currently no measure to prevent or detect
        precision loss, overflow or truncation.
     */
    template < typename DstType, typename SrcType > 
    ::com::sun::star::uno::Sequence< DstType > containerToSequence( const SrcType& i_Container )
    {
        ::com::sun::star::uno::Sequence< DstType > result( i_Container.size() );
        ::std::copy( i_Container.begin(), i_Container.end(), result.getArray() );
        return result;
    }

	//-------------------------------------------------------------------------
	/** Copy from a Sequence into a container

        @tpl SrcType
        Sequence element type. Must be assignable to SrcType's
        elements

    	@tpl DstType
        Container type. This type must fulfill the STL container and
        sequence concepts, in particular, the begin(), end() and the
        unary constructor DstType(int) methods must be available and
        have the usual semantics.

        @param i_Sequence
        Reference to a Sequence of SrcType elements

        @return a pointer to the generated container

        @attention this function always performs a copy. Furthermore,
        when copying from e.g. a Sequence<double> to a vector<int>, no
        proper rounding will be performed, but the values will be
        truncated. There's currently no measure to prevent or detect
        precision loss, overflow or truncation.
     */
    template < typename DstType, typename SrcType > 
    DstType sequenceToContainer( const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence )
    {
        DstType result( i_Sequence.getLength() );
        ::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), result.begin() );
        return result;
    }

Note that the SrcType can usually be deduced by your compiler, thus, one tends to write something like this:

uno::Sequence< double > mySequence;
.
.
.
const std::vector<double>& rMyData(
      comphelper::sequenceToContainer< std::vector<double> >(
           mySequence ));
Personal tools