Kaydet (Commit) 9e8564af authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Simplify o3tl::LazyUpdate

Change-Id: I7569a20877411a5ceb4a7475d82cb634eb6cb114
üst f965b108
......@@ -46,7 +46,7 @@ using namespace canvas;
namespace
{
inline uno::Sequence< double > color2Sequence( sal_Int32 const& nColor )
inline uno::Sequence< double > color2Sequence( sal_Int32 nColor )
{
// TODO(F3): Color management
uno::Sequence< double > aRes( 4 );
......@@ -84,13 +84,13 @@ namespace
{
o3tl::LazyUpdate<sal_Int32,
uno::Sequence<double>,
o3tl::LAZYUPDATE_FUNCTION_TAG > m_aPenColor;
decltype(&color2Sequence)> m_aPenColor;
o3tl::LazyUpdate<sal_Int32,
uno::Sequence<double>,
o3tl::LAZYUPDATE_FUNCTION_TAG > m_aFillColor;
decltype(&color2Sequence)> m_aFillColor;
o3tl::LazyUpdate<geometry::RealRectangle2D,
uno::Reference< rendering::XPolyPolygon2D >,
o3tl::LAZYUPDATE_FUNCTOR_TAG > m_aRectClip;
boost::function1<uno::Reference<rendering::XPolyPolygon2D>, geometry::RealRectangle2D> > m_aRectClip;
geometry::AffineMatrix2D m_aTransformation;
explicit SimpleRenderState( uno::Reference<rendering::XGraphicDevice> const& xDevice ) :
......@@ -367,7 +367,7 @@ namespace
typedef o3tl::LazyUpdate<
rendering::FontRequest,
uno::Reference< rendering::XCanvasFont >,
o3tl::LAZYUPDATE_FUNCTOR_TAG > SimpleFont;
boost::function1<uno::Reference<rendering::XCanvasFont>, rendering::FontRequest> > SimpleFont;
uno::Reference<rendering::XCanvas> mxCanvas;
SimpleFont maFont;
......
......@@ -20,8 +20,9 @@
#ifndef INCLUDED_O3TL_LAZY_UPDATE_HXX
#define INCLUDED_O3TL_LAZY_UPDATE_HXX
#include <sal/types.h>
#include <boost/function.hpp>
#include <sal/config.h>
#include <utility>
namespace o3tl
{
......@@ -35,7 +36,7 @@ namespace o3tl
@example
<pre>
LazyUpdate<InType,OutType,LAZYUPDATE_DIRECT_TAG> myValue;
LazyUpdate<InType,OutType,decltype(F)> myValue(F);
*myValue = newInput;
myValue->updateInput( this, that, those );
......@@ -47,208 +48,47 @@ 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 this->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 this->implUpdateValue(m_aInput); }
output_type const* operator->() const { return &(this->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;
}
template<typename In, typename Out, typename Func> class LazyUpdate {
public:
LazyUpdate(Func const & func): func_(func), input_(), dirty_(true) {}
mutable output_type m_aOutput;
mutable bool m_bCacheDirty; // when true, m_aOutput needs update
};
template<typename T> void setInValue(T && in) {
dirty_ = true;
input_ = std::forward(in);
}
template< typename InputType, typename OutputType, typename FunctionType > struct FunctionPointer
{
protected:
typedef OutputType output_type;
typedef InputType input_type;
typedef FunctionType function_type;
In const & getInValue() const { return input_; }
FunctionPointer() :
m_pFunc(),
m_aOutput(),
m_bCacheDirty(true)
Out const & getOutValue() const { return update(); }
{}
In & operator *() {
dirty_ = true;
return input_;
}
explicit FunctionPointer( function_type const& pFunc ) :
m_pFunc(pFunc),
m_aOutput(),
m_bCacheDirty(true)
In * operator ->() {
dirty_ = true;
return &input_;
}
{}
Out const & operator *() const { return update(); }
output_type const& implUpdateValue( input_type const& rIn ) const
{
if( m_bCacheDirty )
{
m_aOutput = m_pFunc( rIn );
m_bCacheDirty = false;
}
Out const * operator ->() const { return &update(); }
return m_aOutput;
private:
Out const & update() const {
if (dirty_) {
output_ = func_(input_);
dirty_ = false;
}
return output_;
}
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 )
{}
Func const func_;
In input_;
mutable Out output_;
mutable bool dirty_;
};
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment