xref: /aosp_15_r20/external/swiftshader/src/Device/Memset.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #ifndef sw_Memset_hpp
16*03ce13f7SAndroid Build Coastguard Worker #define sw_Memset_hpp
17*03ce13f7SAndroid Build Coastguard Worker 
18*03ce13f7SAndroid Build Coastguard Worker #include <cstring>
19*03ce13f7SAndroid Build Coastguard Worker #include <type_traits>
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker // GCC 8+ warns that
22*03ce13f7SAndroid Build Coastguard Worker // "'void* memset(void*, int, size_t)' clearing an object of non-trivial type 'T';
23*03ce13f7SAndroid Build Coastguard Worker //  use assignment or value-initialization instead [-Werror=class-memaccess]"
24*03ce13f7SAndroid Build Coastguard Worker // This is benign iff it happens before any of the base or member constructors are called.
25*03ce13f7SAndroid Build Coastguard Worker #if defined(__GNUC__) && (__GNUC__ >= 8)
26*03ce13f7SAndroid Build Coastguard Worker #	pragma GCC diagnostic push
27*03ce13f7SAndroid Build Coastguard Worker #	pragma GCC diagnostic ignored "-Wclass-memaccess"
28*03ce13f7SAndroid Build Coastguard Worker #endif
29*03ce13f7SAndroid Build Coastguard Worker 
30*03ce13f7SAndroid Build Coastguard Worker namespace sw {
31*03ce13f7SAndroid Build Coastguard Worker 
32*03ce13f7SAndroid Build Coastguard Worker // Memset<> is a helper class for clearing the memory of objects at construction.
33*03ce13f7SAndroid Build Coastguard Worker // It is useful as the *first* base class of map keys which may contain padding
34*03ce13f7SAndroid Build Coastguard Worker // bytes or bits otherwise left uninitialized.
35*03ce13f7SAndroid Build Coastguard Worker template<class T>
36*03ce13f7SAndroid Build Coastguard Worker struct Memset
37*03ce13f7SAndroid Build Coastguard Worker {
Memsetsw::Memset38*03ce13f7SAndroid Build Coastguard Worker 	Memset(T *object, int val)
39*03ce13f7SAndroid Build Coastguard Worker 	{
40*03ce13f7SAndroid Build Coastguard Worker 		static_assert(std::is_base_of<Memset<T>, T>::value, "Memset<T> must only clear the memory of a type of which it is a base class");
41*03ce13f7SAndroid Build Coastguard Worker 		static_assert(!std::is_polymorphic<T>::value, "Memset<T> must not be used with classes that have virtual functions");
42*03ce13f7SAndroid Build Coastguard Worker 		::memset(object, 0, sizeof(T));
43*03ce13f7SAndroid Build Coastguard Worker 	}
44*03ce13f7SAndroid Build Coastguard Worker 
45*03ce13f7SAndroid Build Coastguard Worker 	// Don't rely on the implicitly declared copy constructor and copy assignment operator.
46*03ce13f7SAndroid Build Coastguard Worker 	// They can leave padding bytes uninitialized.
Memsetsw::Memset47*03ce13f7SAndroid Build Coastguard Worker 	Memset(const Memset &rhs)
48*03ce13f7SAndroid Build Coastguard Worker 	{
49*03ce13f7SAndroid Build Coastguard Worker 		::memcpy(this, &rhs, sizeof(T));
50*03ce13f7SAndroid Build Coastguard Worker 	}
51*03ce13f7SAndroid Build Coastguard Worker 
operator =sw::Memset52*03ce13f7SAndroid Build Coastguard Worker 	Memset &operator=(const Memset &rhs)
53*03ce13f7SAndroid Build Coastguard Worker 	{
54*03ce13f7SAndroid Build Coastguard Worker 		::memcpy(this, &rhs, sizeof(T));
55*03ce13f7SAndroid Build Coastguard Worker 		return *this;
56*03ce13f7SAndroid Build Coastguard Worker 	}
57*03ce13f7SAndroid Build Coastguard Worker 
58*03ce13f7SAndroid Build Coastguard Worker 	// The compiler won't declare an implicit move constructor and move assignment operator
59*03ce13f7SAndroid Build Coastguard Worker 	// due to having a user-defined copy constructor and copy assignment operator. Delete
60*03ce13f7SAndroid Build Coastguard Worker 	// them for explicitness. We always want memcpy() being called.
61*03ce13f7SAndroid Build Coastguard Worker 	Memset(const Memset &&rhs) = delete;
62*03ce13f7SAndroid Build Coastguard Worker 	Memset &operator=(const Memset &&rhs) = delete;
63*03ce13f7SAndroid Build Coastguard Worker 
operator ==(const T & a,const T & b)64*03ce13f7SAndroid Build Coastguard Worker 	friend bool operator==(const T &a, const T &b)
65*03ce13f7SAndroid Build Coastguard Worker 	{
66*03ce13f7SAndroid Build Coastguard Worker 		return ::memcmp(&a, &b, sizeof(T)) == 0;
67*03ce13f7SAndroid Build Coastguard Worker 	}
68*03ce13f7SAndroid Build Coastguard Worker 
operator !=(const T & a,const T & b)69*03ce13f7SAndroid Build Coastguard Worker 	friend bool operator!=(const T &a, const T &b)
70*03ce13f7SAndroid Build Coastguard Worker 	{
71*03ce13f7SAndroid Build Coastguard Worker 		return ::memcmp(&a, &b, sizeof(T)) != 0;
72*03ce13f7SAndroid Build Coastguard Worker 	}
73*03ce13f7SAndroid Build Coastguard Worker 
operator <(const T & a,const T & b)74*03ce13f7SAndroid Build Coastguard Worker 	friend bool operator<(const T &a, const T &b)
75*03ce13f7SAndroid Build Coastguard Worker 	{
76*03ce13f7SAndroid Build Coastguard Worker 		return ::memcmp(&a, &b, sizeof(T)) < 0;
77*03ce13f7SAndroid Build Coastguard Worker 	}
78*03ce13f7SAndroid Build Coastguard Worker };
79*03ce13f7SAndroid Build Coastguard Worker 
80*03ce13f7SAndroid Build Coastguard Worker }  // namespace sw
81*03ce13f7SAndroid Build Coastguard Worker 
82*03ce13f7SAndroid Build Coastguard Worker // Restore -Wclass-memaccess
83*03ce13f7SAndroid Build Coastguard Worker #if defined(__GNUC__) && (__GNUC__ >= 8)
84*03ce13f7SAndroid Build Coastguard Worker #	pragma GCC diagnostic pop
85*03ce13f7SAndroid Build Coastguard Worker #endif
86*03ce13f7SAndroid Build Coastguard Worker 
87*03ce13f7SAndroid Build Coastguard Worker #endif  // sw_Memset_hpp