]> git.lyx.org Git - lyx.git/blob - src/support/RefChanger.h
Re-fix #11146 with recent LaTeX
[lyx.git] / src / support / RefChanger.h
1 // -*- C++ -*-
2 /**
3  * \file RefChanger.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Guillaume Munch
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #ifndef LYX_REFCHANGER_H
13 #define LYX_REFCHANGER_H
14
15 #include "support/Changer.h"
16
17
18 namespace lyx {
19
20 /// A RefChanger records the current value of \param ref, allowing to
21 /// temporarily assign new values to it.  The original value is restored
22 /// automatically when the object is destroyed, unless it is disabled.
23 ///
24 /// RefChanger is movable, and doing so prolongs the duration of the temporary
25 /// assignment. This allows classes to supply their own changer methods.
26 ///
27 /// Naturally, be careful not to extend the life of a RefChanger beyond that of
28 /// the reference it modifies. The RefChanger can be disabled by calling
29 /// ->keep() or ->revert(). Once disabled, the reference is never accessed
30 /// again.
31 template<typename X>
32 class RevertibleRef : public Revertible {
33 public:
34         RevertibleRef(X & ref) : ref(ref), old(ref), enabled(true) {}
35         //
36         ~RevertibleRef() { revert(); }
37         //
38         void revert() { if (enabled) { enabled = false; ref = old; } }
39         //
40         void keep() { enabled = false; }
41         //
42         X & ref;
43         X const old;
44 private:
45         bool enabled;
46 };
47
48
49 template <typename X> using RefChanger = unique_ptr<RevertibleRef<X>>;
50
51
52 /// Saves the value of \param ref in a movable object
53 template <typename X> RefChanger<X> make_save(X & ref)
54 {
55         return make_unique<RevertibleRef<X>>(ref);
56 }
57
58 /// Temporarily assign value val to reference ref.
59 /// To apply the change conditionnally, one can write:
60 ///     Changer dummy = (cond) ? make_change(a, b) : Changer();
61 template <typename X>
62 RefChanger<X> make_change(X & ref, X const val)
63 {
64         auto rc = make_save(ref);
65         ref = val;
66         return rc;
67 }
68
69
70 } // namespace lyx
71
72
73 #endif //LYX_REFCHANGER_H