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