Lumiera  0.pre.03
»edit your freedom«
transiently.hpp
Go to the documentation of this file.
1 /*
2  TRANSIENTLY.hpp - temporary manipulations undone when leaving scope
3 
4  Copyright (C) Lumiera.org
5  2023, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
36 #ifndef LIB_TEST_TRANSIENTLY_H
37 #define LIB_TEST_TRANSIENTLY_H
38 
39 
40 #include "lib/nocopy.hpp"
41 #include "lib/meta/function.hpp"
42 #include "lib/ppmpl.h"
43 
44 #include <utility>
45 
46 namespace lib {
47 namespace test{
48 
53  template<typename TAR>
56  {
57  TAR originalVal_;
58  TAR& manipulated_;
59 
60  public:
61  Transiently(TAR& target)
62  : originalVal_{target}
63  , manipulated_{target}
64  { }
65 
66  ~Transiently()
67  {
68  manipulated_ = std::move (originalVal_);
69  }
70 
71  template<typename X>
72  void
73  operator= (X&& x)
74  {
75  manipulated_ = std::forward<X> (x);
76  }
77  };
78 
79 
81  template<>
82  class Transiently<void(void)>
84  {
85  using Manipulator = std::function<void(void)>;
86 
87  Manipulator doIt_;
88  Manipulator undoIt_;
89 
90  public:
91  Transiently (Manipulator manipulation)
92  : doIt_{std::move (manipulation)}
93  , undoIt_{}
94  { }
95 
96  ~Transiently()
97  {
98  CHECK (undoIt_, "REJECT Manipulation -- "
99  "Failed to provide a way "
100  "to undo the manipulation.");
101  undoIt_();
102  }
103 
104  void
105  cleanUp (Manipulator cleanUp)
106  {
107  undoIt_ = std::move (cleanUp);
108  doIt_(); // actually perform the manipulation
109  }
110  };
111 
116  template<typename FUN, typename=lib::meta::enable_if<lib::meta::has_Sig<FUN, void(void)>>>
118 
119 }} // namespace lib::test
120 
121 
122 
123 
124 /* === test helper macros === */
125 
130 #define TRANSIENTLY(_OO_) \
131  lib::test::Transiently PPMPL_CAT(transientlyManipulated_,__LINE__)(_OO_); PPMPL_CAT(transientlyManipulated_,__LINE__)
132 
133 
134 #endif /*LIB_TEST_TRANSIENTLY_H*/
Definition: run.hpp:49
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
Implementation namespace for support and library code.
Variation where manipulation is done by λ
Definition: transiently.hpp:82
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Metaprogramming tools for transforming functor types.
Preprocessor metaprogramming library.
Token to capture a value and restore original when leaving scope.
Definition: transiently.hpp:54