mesa: Restore 78-column wrapping of license text in C++-style comments.
[mesa.git] / src / gallium / state_trackers / clover / core / module.cpp
1 //
2 // Copyright 2012 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 #include <type_traits>
24 #include <algorithm>
25
26 #include "core/module.hpp"
27
28 using namespace clover;
29
30 namespace {
31 template<typename T, typename = void>
32 struct __serializer;
33
34 /// Serialize the specified object.
35 template<typename T>
36 void
37 __proc(compat::ostream &os, const T &x) {
38 __serializer<T>::proc(os, x);
39 }
40
41 /// Deserialize the specified object.
42 template<typename T>
43 void
44 __proc(compat::istream &is, T &x) {
45 __serializer<T>::proc(is, x);
46 }
47
48 template<typename T>
49 T
50 __proc(compat::istream &is) {
51 T x;
52 __serializer<T>::proc(is, x);
53 return x;
54 }
55
56 /// (De)serialize a scalar value.
57 template<typename T>
58 struct __serializer<T, typename std::enable_if<
59 std::is_scalar<T>::value>::type> {
60 static void
61 proc(compat::ostream &os, const T &x) {
62 os.write(reinterpret_cast<const char *>(&x), sizeof(x));
63 }
64
65 static void
66 proc(compat::istream &is, T &x) {
67 is.read(reinterpret_cast<char *>(&x), sizeof(x));
68 }
69 };
70
71 /// (De)serialize a vector.
72 template<typename T>
73 struct __serializer<compat::vector<T>> {
74 static void
75 proc(compat::ostream &os, const compat::vector<T> &v) {
76 __proc<uint32_t>(os, v.size());
77
78 for (size_t i = 0; i < v.size(); i++)
79 __proc<T>(os, v[i]);
80 }
81
82 static void
83 proc(compat::istream &is, compat::vector<T> &v) {
84 v.reserve(__proc<uint32_t>(is));
85
86 for (size_t i = 0; i < v.size(); i++)
87 new(&v[i]) T(__proc<T>(is));
88 }
89 };
90
91 /// (De)serialize a module::section.
92 template<>
93 struct __serializer<module::section> {
94 template<typename S, typename QT>
95 static void
96 proc(S &s, QT &x) {
97 __proc(s, x.id);
98 __proc(s, x.type);
99 __proc(s, x.size);
100 __proc(s, x.data);
101 }
102 };
103
104 /// (De)serialize a module::argument.
105 template<>
106 struct __serializer<module::argument> {
107 template<typename S, typename QT>
108 static void
109 proc(S &s, QT &x) {
110 __proc(s, x.type);
111 __proc(s, x.size);
112 }
113 };
114
115 /// (De)serialize a module::symbol.
116 template<>
117 struct __serializer<module::symbol> {
118 template<typename S, typename QT>
119 static void
120 proc(S &s, QT &x) {
121 __proc(s, x.name);
122 __proc(s, x.section);
123 __proc(s, x.offset);
124 __proc(s, x.args);
125 }
126 };
127
128 /// (De)serialize a module.
129 template<>
130 struct __serializer<module> {
131 template<typename S, typename QT>
132 static void
133 proc(S &s, QT &x) {
134 __proc(s, x.syms);
135 __proc(s, x.secs);
136 }
137 };
138 };
139
140 namespace clover {
141 void
142 module::serialize(compat::ostream &os) const {
143 __proc(os, *this);
144 }
145
146 module
147 module::deserialize(compat::istream &is) {
148 return __proc<module>(is);
149 }
150
151 const module::symbol &
152 module::sym(compat::string name) const {
153 auto it = std::find_if(syms.begin(), syms.end(), [&](const symbol &x) {
154 return compat::string(x.name) == name;
155 });
156
157 if (it == syms.end())
158 throw noent_error();
159
160 return *it;
161 }
162
163 const module::section &
164 module::sec(typename section::type type) const {
165 auto it = std::find_if(secs.begin(), secs.end(), [&](const section &x) {
166 return x.type == type;
167 });
168
169 if (it == secs.end())
170 throw noent_error();
171
172 return *it;
173 }
174 }