diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2007-06-27 11:15:38 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2007-06-27 11:15:38 +0000 |
commit | b80c937dc6b8d3a6a511f5fc82b0ab7e2172c9d1 (patch) | |
tree | 15ca692803f26e991454f2ffa4ddf7291ee93613 | |
parent | e16d669c8ae786bee4720246dd298a5a27818f4f (diff) |
INTEGRATION: CWS awttree01 (1.1.2); FILE ADDED
2007/05/21 13:36:16 thb 1.1.2.2: #i10000# Made this work for gcc3.x
2007/04/25 12:10:11 thb 1.1.2.1: #i75289# Added caching helper, to easy lazy update behaviour in XSimpleCanvas implementation
-rw-r--r-- | o3tl/inc/o3tl/lazy_update.hxx | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/o3tl/inc/o3tl/lazy_update.hxx b/o3tl/inc/o3tl/lazy_update.hxx new file mode 100644 index 000000000000..8479f522f91e --- /dev/null +++ b/o3tl/inc/o3tl/lazy_update.hxx @@ -0,0 +1,279 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: lazy_update.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-06-27 12:15:38 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_O3TL_LAZY_UPDATE_HXX +#define INCLUDED_O3TL_LAZY_UPDATE_HXX + +#include <sal/types.h> +#include <boost/function.hpp> + +namespace o3tl +{ + /** Update output object lazily + + This template collects data in input type, and updates the + output type with the given update functor, but only if the + output is requested. Usefl if updating is expensive, or input + changes frequently, but output is only comparatively seldom + used. + + @example + <pre> +LazyUpdate<InType,OutType,LAZYUPDATE_DIRECT_TAG> myValue; +*myValue = newInput; +myValue->updateInput( this, that, those ); + +output( *myValue ); + </pre> + or + <pre> +output( myValue.getOutValue() ); + </pre> + if the compiler does not recognize the const context. + */ + template< typename InputType, typename OutputType, typename Tag > class LazyUpdate; + + /// LazyUpdate specialization takes boost::function argument + struct LAZYUPDATE_FUNCTOR_TAG {}; + /// LazyUpdate specialization takes OutputType (*FunctionType)( InputType const& ) argument + struct LAZYUPDATE_FUNCTION_TAG {}; + /// LazyUpdate specialization can directly convert, OutputType ctor must take InputType argument + struct LAZYUPDATE_DIRECT_TAG {}; + + // ----------------------------------------------------------------------------------------------------- + + namespace detail + { + /// @internal + template< typename InputType, typename OutputType, typename Functor > class LazyUpdateImpl : private Functor + { + public: + typedef OutputType output_type; + typedef InputType input_type; + + LazyUpdateImpl() : + m_aInput() + {} + + template< typename ParamType > explicit LazyUpdateImpl( ParamType const& rParm ) : + Functor(rParm), + m_aInput() + {} + + enum UnaryConstructorTag{ UNARY_CONSTRUCTOR_TAG }; + LazyUpdateImpl( const input_type& rInput, UnaryConstructorTag ) : + m_aInput(rInput) + {} + + template< typename ParamType > LazyUpdateImpl( ParamType const& rParm, + const input_type& rInput ) : + Functor(rParm), + m_aInput(rInput) + {} + + // default copy ctor/assignment operator are ok + // LazyUpdate( const LazyUpdate& ); + // LazyUpdate& operator=( const LazyUpdate& ); + + void setInValue( input_type const& rIn ) { Functor::m_bCacheDirty = true; m_aInput = rIn; } + input_type const& getInValue() const { return m_aInput; } + output_type const& getOutValue() const { return implUpdateValue(m_aInput); } + + input_type& operator*() { Functor::m_bCacheDirty = true; return m_aInput; } + input_type* operator->() { Functor::m_bCacheDirty = true; return &m_aInput; } + + output_type const& operator*() const { return implUpdateValue(m_aInput); } + output_type const* operator->() const { return &implUpdateValue(m_aInput); } + + private: + input_type m_aInput; + }; + + template< typename InputType, typename OutputType > struct DefaultFunctor + { + protected: + typedef OutputType output_type; + typedef InputType input_type; + + DefaultFunctor() : + m_aOutput(), + m_bCacheDirty(true) + {} + + OutputType const& implUpdateValue( input_type const& rIn ) const + { + if( m_bCacheDirty ) + { + m_aOutput = output_type( rIn ); + m_bCacheDirty = false; + } + + return m_aOutput; + } + + mutable output_type m_aOutput; + mutable bool m_bCacheDirty; // when true, m_aOutput needs update + }; + + template< typename InputType, typename OutputType, typename FunctionType > struct FunctionPointer + { + protected: + typedef OutputType output_type; + typedef InputType input_type; + typedef FunctionType function_type; + + FunctionPointer() : + m_pFunc(), + m_aOutput(), + m_bCacheDirty(true) + + {} + + explicit FunctionPointer( function_type const& pFunc ) : + m_pFunc(pFunc), + m_aOutput(), + m_bCacheDirty(true) + + {} + + output_type const& implUpdateValue( input_type const& rIn ) const + { + if( m_bCacheDirty ) + { + m_aOutput = m_pFunc( rIn ); + m_bCacheDirty = false; + } + + return m_aOutput; + } + + function_type m_pFunc; + mutable output_type m_aOutput; + mutable bool m_bCacheDirty; // when true, m_aOutput needs update + }; + } + + // ----------------------------------------------------------------------------------------------------- + + // partial specializations for the three LAZYUPDATE_* tags + + template< typename InputType, typename OutputType > class LazyUpdate<InputType, + OutputType, + LAZYUPDATE_DIRECT_TAG> : + public detail::LazyUpdateImpl<InputType, + OutputType, + detail::DefaultFunctor<InputType, OutputType> > + { + public: + LazyUpdate() {} + explicit LazyUpdate( InputType const& rIn ) : + detail::LazyUpdateImpl<InputType, + OutputType, + detail::DefaultFunctor<InputType, OutputType> >( + rIn, + detail::LazyUpdateImpl< + InputType, + OutputType, + detail::DefaultFunctor<InputType, OutputType> >::UNARY_CONSTRUCTOR_TAG ) + {} + }; + + // ----------------------------------------------------------------------------------------------------- + + template< typename InputType, typename OutputType > class LazyUpdate<InputType, + OutputType, + LAZYUPDATE_FUNCTION_TAG> : + public detail::LazyUpdateImpl<InputType, + OutputType, + detail::FunctionPointer< + InputType, + OutputType, + OutputType (*)( InputType const& ) > > + { + public: + explicit LazyUpdate( OutputType (*pFunc)( InputType const& ) ) : + detail::LazyUpdateImpl<InputType, + OutputType, + detail::FunctionPointer< + InputType, + OutputType, + OutputType (*)( InputType const& )> >(pFunc) + {} + LazyUpdate( OutputType (*pFunc)( InputType const& ), + InputType const& rIn ) : + detail::LazyUpdateImpl<InputType, + OutputType, + detail::FunctionPointer< + InputType, + OutputType, + OutputType (*)( InputType const& )> >(pFunc,rIn) + {} + }; + + // ----------------------------------------------------------------------------------------------------- + + template< typename InputType, typename OutputType > class LazyUpdate<InputType, + OutputType, + LAZYUPDATE_FUNCTOR_TAG> : + public detail::LazyUpdateImpl<InputType, + OutputType, + detail::FunctionPointer< + InputType, + OutputType, + boost::function1<OutputType,InputType> > > + { + public: + explicit LazyUpdate( boost::function1<OutputType,InputType> const& rFunc ) : + detail::LazyUpdateImpl<InputType, + OutputType, + detail::FunctionPointer< + InputType, + OutputType, + boost::function1<OutputType,InputType> > >(rFunc) + {} + LazyUpdate( boost::function1<OutputType,InputType> const& rFunc, + InputType const& rIn ) : + detail::LazyUpdateImpl<InputType, + OutputType, + detail::FunctionPointer< + InputType, + OutputType, + boost::function1<OutputType,InputType> > >(rFunc,rIn) + {} + }; + +} + +#endif /* INCLUDED_O3TL_LAZY_UPDATE_HXX */ |