~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/frontends/clover/util/lazy.hpp

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// Copyright 2013 Francisco Jerez
3
 
//
4
 
// Permission is hereby granted, free of charge, to any person obtaining a
5
 
// copy of this software and associated documentation files (the "Software"),
6
 
// to deal in the Software without restriction, including without limitation
7
 
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 
// and/or sell copies of the Software, and to permit persons to whom the
9
 
// Software is furnished to do so, subject to the following conditions:
10
 
//
11
 
// The above copyright notice and this permission notice shall be included in
12
 
// all copies or substantial portions of the Software.
13
 
//
14
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18
 
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
 
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
 
// OTHER DEALINGS IN THE SOFTWARE.
21
 
//
22
 
 
23
 
#ifndef CLOVER_UTIL_LAZY_HPP
24
 
#define CLOVER_UTIL_LAZY_HPP
25
 
 
26
 
#include <type_traits>
27
 
#include <stdexcept>
28
 
#include <memory>
29
 
 
30
 
namespace clover {
31
 
   namespace detail {
32
 
      template<typename T>
33
 
      class basic_lazy {
34
 
      public:
35
 
         virtual
36
 
         ~basic_lazy() {
37
 
         }
38
 
 
39
 
         virtual basic_lazy *
40
 
         clone() const = 0;
41
 
 
42
 
         virtual
43
 
         operator T() const = 0;
44
 
      };
45
 
 
46
 
      template<typename T, typename F>
47
 
      class deferred_lazy : public basic_lazy<T> {
48
 
      public:
49
 
         template<typename G>
50
 
         deferred_lazy(G &&f) : f(new F(std::forward<G>(f))) {
51
 
         }
52
 
 
53
 
         virtual basic_lazy<T> *
54
 
         clone() const {
55
 
            return new deferred_lazy(*this);
56
 
         }
57
 
 
58
 
         operator T() const {
59
 
            if (f) {
60
 
               x = (*f)();
61
 
               f = {};
62
 
            }
63
 
 
64
 
            return x;
65
 
         }
66
 
 
67
 
      private:
68
 
         mutable std::shared_ptr<F> f;
69
 
         mutable T x;
70
 
      };
71
 
 
72
 
      template<typename T>
73
 
      class strict_lazy : public basic_lazy<T> {
74
 
      public:
75
 
         template<typename S>
76
 
         strict_lazy(S &&x) : x(std::forward<S>(x)) {
77
 
         }
78
 
 
79
 
         virtual basic_lazy<T> *
80
 
         clone() const {
81
 
            return new strict_lazy(*this);
82
 
         }
83
 
 
84
 
         operator T() const {
85
 
            return x;
86
 
         }
87
 
 
88
 
      private:
89
 
         T x;
90
 
      };
91
 
   }
92
 
 
93
 
   ///
94
 
   /// Object that represents a value of type \a T that is calculated
95
 
   /// lazily as soon as it is required.
96
 
   ///
97
 
   template<typename T>
98
 
   class lazy {
99
 
   public:
100
 
      class undefined_error : std::logic_error {
101
 
      public:
102
 
         undefined_error() : std::logic_error("") {
103
 
         }
104
 
      };
105
 
 
106
 
      ///
107
 
      /// Initialize to some fixed value \a x which isn't calculated
108
 
      /// lazily.
109
 
      ///
110
 
      lazy(T x) : obj(new detail::strict_lazy<T>(x)) {
111
 
      }
112
 
 
113
 
      ///
114
 
      /// Initialize by providing a functor \a f that will calculate
115
 
      /// the value on-demand.
116
 
      ///
117
 
      template<typename F>
118
 
      lazy(F &&f) : obj(new detail::deferred_lazy<
119
 
                           T, typename std::remove_reference<F>::type
120
 
                        >(std::forward<F>(f))) {
121
 
      }
122
 
 
123
 
      ///
124
 
      /// Initialize to undefined.
125
 
      ///
126
 
      lazy() : lazy([]() {
127
 
               throw undefined_error();
128
 
               return T();
129
 
            }) {
130
 
      }
131
 
 
132
 
      lazy(const lazy &other) : obj(obj->clone()) {
133
 
      }
134
 
 
135
 
      lazy(lazy &&other) : obj(NULL) {
136
 
         std::swap(obj, other.obj);
137
 
      }
138
 
 
139
 
      ~lazy() {
140
 
         delete obj;
141
 
      }
142
 
 
143
 
      lazy &
144
 
      operator=(lazy other) {
145
 
         std::swap(obj, other.obj);
146
 
         return *this;
147
 
      }
148
 
 
149
 
      ///
150
 
      /// Evaluate the value.
151
 
      ///
152
 
      operator T() const {
153
 
         return *obj;
154
 
      }
155
 
 
156
 
   private:
157
 
      detail::basic_lazy<T> *obj;
158
 
   };
159
 
}
160
 
 
161
 
#endif