]> git.lyx.org Git - lyx.git/blob - src/support/RefChanger.h
Account for old versions of Pygments
[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 //for gcc 4.6
50 #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 6)
51 template <typename X>
52 struct RefChanger : unique_ptr<RevertibleRef<X>>
53 {
54         RefChanger(unique_ptr<RevertibleRef<X>> p)
55                 : unique_ptr<RevertibleRef<X>>(move(p))
56                 {}
57 };
58 #else
59 template <typename X> using RefChanger = unique_ptr<RevertibleRef<X>>;
60 #endif
61
62
63 /// Saves the value of \param ref in a movable object
64 template <typename X> RefChanger<X> make_save(X & ref)
65 {
66         return make_unique<RevertibleRef<X>>(ref);
67 }
68
69 /// Temporarily assign value val to reference ref.
70 /// To apply the change conditionnally, one can write:
71 ///     Changer dummy = (cond) ? make_change(a, b) : Changer();
72 template <typename X>
73 RefChanger<X> make_change(X & ref, X const val)
74 {
75         auto rc = make_save(ref);
76         ref = val;
77         return rc;
78 }
79
80
81 }
82
83
84 #endif //LYX_REFCHANGER_H