// Copyright (c) 2015-2016 The Khronos Group Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef SOURCE_UTIL_BITUTILS_H_ #define SOURCE_UTIL_BITUTILS_H_ #include <cassert> #include <cstdint> #include <cstring> #include <type_traits> namespace spvtools { namespace utils { // Performs a bitwise copy of source to the destination type Dest. template <typename Dest, typename Src> Dest BitwiseCast(Src source) { … } // Calculates the bit width of the integer type |T|. template <typename T> struct IntegerBitWidth { … }; // SetBits<T, First, Num> returns an integer of type <T> with bits set // for position <First> through <First + Num - 1>, counting from the least // significant bit. In particular when Num == 0, no positions are set to 1. // A static assert will be triggered if First + Num > sizeof(T) * 8, that is, // a bit that will not fit in the underlying type is set. template <typename T, size_t First = 0, size_t Num = 0> struct SetBits { … }; SetBits<T, Last, 0>; // This is all compile-time so we can put our tests right here. static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; // Returns number of '1' bits in a word. template <typename T> size_t CountSetBits(T word) { … } // Checks if the bit at the |position| is set to '1'. // Bits zero-indexed starting at the least significant bit. // |position| must be within the bit width of |T|. template <typename T> bool IsBitAtPositionSet(T word, size_t position) { … } // Returns a value obtained by setting a range of adjacent bits of |word| to // |value|. Affected bits are within the range: // [first_position, first_position + num_bits_to_mutate), // assuming zero-based indexing starting at the least // significant bit. Bits to mutate must be within the bit width of |T|. template <typename T> T MutateBits(T word, size_t first_position, size_t num_bits_to_mutate, bool value) { … } // Returns a value obtained by setting the |num_bits_to_set| highest bits to // '1'. |num_bits_to_set| must be not be greater than the bit width of |T|. template <typename T> T SetHighBits(T word, size_t num_bits_to_set) { … } // Returns a value obtained by setting the |num_bits_to_set| highest bits to // '0'. |num_bits_to_set| must be not be greater than the bit width of |T|. template <typename T> T ClearHighBits(T word, size_t num_bits_to_set) { … } // Returns the value obtained by extracting the |number_of_bits| least // significant bits from |value|, and sign-extending it to 64-bits. template <typename T> T SignExtendValue(T value, uint32_t number_of_bits) { … } // Returns the value obtained by extracting the |number_of_bits| least // significant bits from |value|, and zero-extending it to 64-bits. template <typename T> T ZeroExtendValue(T value, uint32_t number_of_bits) { … } } // namespace utils } // namespace spvtools #endif // SOURCE_UTIL_BITUTILS_H_