Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef INCLUDED_O3TL_LAZY_UPDATE_HXX
21 : #define INCLUDED_O3TL_LAZY_UPDATE_HXX
22 :
23 : #include <sal/config.h>
24 :
25 : #include <utility>
26 :
27 : namespace o3tl
28 : {
29 : /** Update output object lazily
30 :
31 : This template collects data in input type, and updates the
32 : output type with the given update functor, but only if the
33 : output is requested. Useful if updating is expensive, or input
34 : changes frequently, but output is only comparatively seldom
35 : used.
36 :
37 : @example
38 : <pre>
39 : LazyUpdate<InType,OutType,decltype(F)> myValue(F);
40 : *myValue = newInput;
41 : myValue->updateInput( this, that, those );
42 :
43 : output( *myValue );
44 : </pre>
45 : or
46 : <pre>
47 : output( myValue.getOutValue() );
48 : </pre>
49 : if the compiler does not recognize the const context.
50 : */
51 0 : template<typename In, typename Out, typename Func> class LazyUpdate {
52 : public:
53 0 : LazyUpdate(Func const & func): func_(func), input_(), dirty_(true) {}
54 :
55 : template<typename T> void setInValue(T && in) {
56 : dirty_ = true;
57 : input_ = std::forward(in);
58 : }
59 :
60 0 : In const & getInValue() const { return input_; }
61 :
62 0 : Out const & getOutValue() const { return update(); }
63 :
64 0 : In & operator *() {
65 0 : dirty_ = true;
66 0 : return input_;
67 : }
68 :
69 0 : In * operator ->() {
70 0 : dirty_ = true;
71 0 : return &input_;
72 : }
73 :
74 0 : Out const & operator *() const { return update(); }
75 :
76 : Out const * operator ->() const { return &update(); }
77 :
78 : private:
79 0 : Out const & update() const {
80 0 : if (dirty_) {
81 0 : output_ = func_(input_);
82 0 : dirty_ = false;
83 : }
84 0 : return output_;
85 : }
86 :
87 : Func const func_;
88 : In input_;
89 : mutable Out output_;
90 : mutable bool dirty_;
91 : };
92 : }
93 :
94 : #endif
95 :
96 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|