1fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/* 2fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Copyright 2016 The Android Open Source Project 3fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * 4fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License"); 5fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * you may not use this file except in compliance with the License. 6fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * You may obtain a copy of the License at 7fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * 8fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * http://www.apache.org/licenses/LICENSE-2.0 9fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * 10fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Unless required by applicable law or agreed to in writing, software 11fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS, 12fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * See the License for the specific language governing permissions and 14fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * limitations under the License. 15fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar */ 16fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 17fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar//#define LOG_NDEBUG 0 18fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar#define LOG_TAG "Flagged_test" 19fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 20fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar#include <gtest/gtest.h> 21fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 22fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar#include <media/stagefright/foundation/Flagged.h> 23fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 24fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarnamespace android { 25fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 26fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/** 27fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Helper template that can be used to print values in static_assert error messages. 28fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * 29fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * Use integers here. 30fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar */ 31fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnartemplate<bool, int ...N> 32fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarstruct _print_as_warning { }; 33fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 34fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnartemplate<int ...N> 35fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarstruct _print_as_warning<true, N...> : std::true_type { }; 36fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 37fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar#define static_assert_equals(a, b, msg) \ 38fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarstatic_assert(_print_as_warning<(a) == (b), a, b>::value, msg) 39fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 40fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarclass FlaggedTest : public ::testing::Test { 41fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarprotected: 42fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // empty structs 43fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct A0 { }; 44fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct A1 { }; 45fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct A_A0 : public A0 { }; 46fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 47fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // simple struct 48fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct BB { 49fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar int32_t i; 50fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar uint32_t u; 51fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 52fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 53fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // struct inheriting from A0 54fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct BB_A0 : public A0 { 55fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar int32_t i; 56fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar uint32_t u; 57fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 58fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 59fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // struct inheriting from struct inheriting A0 60fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct BB_AA0 : public A_A0 { 61fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar int32_t i; 62fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar uint32_t u; 63fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 64fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 65fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // struct that wraps 66fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct WBBA0 { 67fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar BB_A0 b; 68fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 69fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 70fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct WBBA0_A1 : public A1 { 71fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar BB_A0 b; 72fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 73fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 74fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct WBBA0_A0 : public A0 { 75fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar BB_A0 b; 76fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 77fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 78fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct WBB_A0 : public A0 { 79fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar BB b; 80fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 81fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 82fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct WBBA0_AA0 : public A_A0 { 83fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar BB_A0 b; 84fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 85fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 86fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct WBBAA0_A0 : public A0 { 87fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar BB_AA0 b; 88fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 89fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 90fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar struct WWBBA0_A0 : public A0 { 91fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar WBBA0 b; 92fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 93fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar}; 94fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 95fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar/** 96fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * This test is here to confirm the handling of wrapping classes that inherit from an interface 97fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * while also inheriting from that same interface. While we no longer use this construct, we want 98fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar * to track if this defect is ever fixed. 99fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar */ 100fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos MolnarTEST_F(FlaggedTest, StaticSanityTests) { 101fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(A0) == 1, ""); 102fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(A1) == 1, ""); 103fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(A_A0) == 1, ""); 104fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 105fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static constexpr size_t size = sizeof(BB); // original [pair] 106fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 107fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // inheriting from A0 does not increase size 108fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(BB_A0) == size, ""); // [pair]:A0 109fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(BB_AA0) == size, ""); // [pair]:[:A0] 110fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 111fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // wrapping a class that inherits from A0 does not increase size 112fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(WBBA0) == size, ""); // [ [pair]:[:A0] ] 113fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 114fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // wrapping a class that inherits from A0 while also inheriting from A1 does not increase size 115fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(WBBA0_A1) == size, ""); // [ [pair]:A0 ]:A1 116fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 117fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // wrapping a class that inherits from A0 while also inheriting from A0 DOES increase size 118fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_GT(sizeof(WBBA0_A0), size); // [ [pair]:A0 ]:A0 119fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 120fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // wrapping a class that does not inherit from A0 while inheriting from A0 does not increase 121fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // size 122fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(WBB_A0) == size, ""); // [[pair]]:A0 123fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 124fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // wrapping a class that inherits from A0 while also inheriting from a class that inherits 125fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // from A0 does increase size 126fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_GT(sizeof(WBBA0_AA0), size); // [ [pair]:A0 ]:[:A0] 127fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 128fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // wrapping a class that indirectly inherits from A0 while also inheriting from A0 does 129fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // increase size 130fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_GT(sizeof(WBBAA0_A0), size); // [ [pair]:[:A0] ]:A0 131fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 132fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // wrapping a class that inherits from A0 while also inheriting A0 does increase size 133fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_GT(sizeof(WWBBA0_A0), size); // [ [pair]:A0 ]:A0 134fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar} 135fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 136fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnarenum FLAG : int32_t { 137fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kMask0 = 0x0FF, 138fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kFlag0_A = 0x0AA, 139fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kFlag0_B = 0x0BB, 140fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kFlag0_C = 0x0CC, 141fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kMask1 = 0xFF0, 142fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kFlag1_A = 0xAA0, 143fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kFlag1_B = 0xBB0, 144fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kFlag1_C = 0xCC0, 145fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kMaskCommon = 0x0F0, 146fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar}; 147fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 148fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos MolnarTEST_F(FlaggedTest, BasicExample) { 149fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar enum SafeFlags : uint32_t { 150fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kUnsafe, 151fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kSafe, 152fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kSafeMask = _Flagged_helper::minMask(kSafe), 153fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 154fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<int32_t, SafeFlags, kSafeMask> safeInt32; 155fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 156fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar safeInt32 a(kUnsafe); 157fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar a.setFlags(kSafe); 158fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar a.get() = 15; 159fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(a.flags(), kSafe); 160fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(a.get(), 15); 161fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 162fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar enum OriginFlags : uint32_t { 163fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kUnknown, 164fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kConst, 165fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kCalculated, 166fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kComponent, 167fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kApplication, 168fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kFile, 169fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kBinder, 170fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kOriginMask = _Flagged_helper::minMask(kBinder), 171fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 172fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<safeInt32, OriginFlags, kOriginMask> 173fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar trackedSafeInt32; 174fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 175fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(trackedSafeInt32) == sizeof(safeInt32), ""); 176fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 177fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar trackedSafeInt32 b(kConst, kSafe, 1); 178fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(b.flags(), kConst); 179fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(b.get().flags(), kSafe); 180fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(b.get().get(), 1); 181fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar b.setFlags(kCalculated); 182fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar volatile bool overflow = true; 183fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar b.get().setFlags(overflow ? kUnsafe : kSafe); 184fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 185fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar enum ValidatedFlags : uint32_t { 186fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kUnsafeV = kUnsafe, 187fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kSafeV = kSafe, 188fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kValidated = kSafe | 2, 189fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kSharedMaskV = kSafeMask, 190fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar kValidatedMask = _Flagged_helper::minMask(kValidated), 191fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar }; 192fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<safeInt32, ValidatedFlags, kValidatedMask, kSharedMaskV> validatedInt32; 193fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 194fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar validatedInt32 v(kUnsafeV, kSafe, 10); 195fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(v.flags(), kUnsafeV); 196fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(v.get().flags(), kUnsafe); // !kUnsafeV overrides kSafe 197fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(v.get().get(), 10); 198fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar v.setFlags(kValidated); 199fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(v.flags(), kValidated); 200fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(v.get().flags(), kSafe); 201fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar v.get().setFlags(kUnsafe); 202fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(v.flags(), 2); // NOTE: sharing masks with enums allows strange situations to occur 203fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar} 204fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 205fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos MolnarTEST_F(FlaggedTest, _Flagged_helper_Test) { 206fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar using helper = _Flagged_helper; 207fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 208fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar using i32 = int32_t; 209fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar using u32 = uint32_t; 210fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar using u8 = uint8_t; 211fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 212fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // base2 213fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0u, 0u, 0>::sFlagMask == 0u, ""); 214fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0u, 0u, 0>::sFlagShift == 0, ""); 215fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0u, 0u, 0>::sEffectiveMask == 0u, ""); 216fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 217fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0u, 0u, 10>::sFlagMask == 0u, ""); 218fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0u, 0u, 10>::sFlagShift == 10, ""); 219fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0u, 0u, 10>::sEffectiveMask == 0u, ""); 220fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 221fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0u, 0u, -1>::sFlagMask == 0u, ""); 222fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0u, 0u, -1>::sFlagShift == 0, ""); 223fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0u, 0u, -1>::sEffectiveMask == 0u, ""); 224fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 225fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 99u, 0u, 0>::sFlagMask == 99u, ""); 226fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 99u, 0u, 0>::sFlagShift == 0, ""); 227fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 99u, 0u, 0>::sEffectiveMask == 99u, ""); 228fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 229fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0x99u, 0u, 12>::sFlagMask == 0x99u, ""); 230fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0x99u, 0u, 12>::sFlagShift == 12, ""); 231fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 0x99u, 0u, 12>::sEffectiveMask == 0x99000u, ""); 232fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 233fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 99u, 0u, -1>::sFlagMask == 99u, ""); 234fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 99u, 0u, -1>::sFlagShift == 0, ""); 235fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(Flagged<i32, u32, 99u, 0u, -1>::sEffectiveMask == 99u, ""); 236fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 237fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // mask_of<T, Flag> 238fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // also Flagged<> no default 239fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32, u32, 0x800F /* mask */, 0 /* shared mask */, 0 /* shift */> i32_800f_0; 240fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32, u32, 0x800F /* mask */, 0 /* shared mask */, 4 /* shift */> i32_800f_4; 241fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // this also tests that these types can be instantiated 242fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(i32_800f_0) >= sizeof(i32) + sizeof(u32), 243fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "should be at least size of component types"); 244fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(sizeof(i32_800f_4) == sizeof(i32_800f_0), "regardless of shift"); 245fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!i32_800f_0::sFlagCombined, ""); 246fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!i32_800f_4::sFlagCombined, ""); 247fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 248fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_0, u32>::value == 0x800F, "incorrect mask"); 249fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_0, i32>::value == 0, 250fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "mask should be 0 when types mismatch"); 251fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_0, u32>::effective_value == 0x800F, "incorrect mask"); 252fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_0, i32>::effective_value == 0, 253fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "mask should be 0 when types mismatch"); 254fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_0, u32>::shift == 0, "incorrect shift"); 255fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_0, i32>::shift == 0, 256fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "shift should be 0 when types mismatch"); 257fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 258fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_4, u32>::value == 0x800F, "incorrect mask"); 259fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_4, i32>::value == 0, 260fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "mask should be 0 when types mismatch"); 261fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_4, u32>::effective_value == 0x800F0, "incorrect mask"); 262fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_4, i32>::effective_value == 0, 263fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "mask should be 0 when types mismatch"); 264fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_4, u32>::shift == 4, "incorrect shift"); 265fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32_800f_4, i32>::shift == 0, 266fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "shift should be 0 when types mismatch"); 267fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32, u32>::value == 0, "mask should be 0 if not masked"); 268fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::mask_of<i32, i32>::value == 0, "mask should be 0 if not masked"); 269fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 270fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // lshift(value, n) 271fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::lshift(0U, 0) == 0U, ""); 272fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::lshift(0U, 30) == 0U, ""); 273fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::lshift(1U, 0) == 1U, ""); 274fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::lshift(1U, 10) == 1024U, ""); 275fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::lshift(10U, 10) == 10240U, ""); 276fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::lshift(10, 10) == 10240, ""); 277fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::lshift(-10, 0) == -10, ""); 278fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // static_assert(helper::lshift(-10, 10) == -10240, ""); // error: left shift of negative value 279fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 280fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // minMask(maxValue) 281fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::minMask(0U) == 0U, "lowest 0 bits"); 282fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::minMask(1U) == 1U, "lowest 1 bit"); 283fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::minMask(2U) == 3U, "lowest 2 bits"); 284fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::minMask(3U) == 3U, "lowest 2 bits"); 285fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::minMask(4U) == 7U, "lowest 3 bits"); 286fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::minMask(~0U) == ~0U, "all bits"); 287fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // static_assert(helper::minMask(10) == 0xF, "all bits"); // error: must be unsigned 288fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 289fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // topBits(n) 290fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::topBits<u32>(0) == 0U, "top 0 bit"); 291fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::topBits<u32>(1) == 0x80000000U, "top 1 bit"); 292fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::topBits<u32>(2) == 0xC0000000U, "top 2 bits"); 293fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::topBits<u32>(12) == 0xFFF00000U, "top 12 bits"); 294fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::topBits<u32>(32) == 0xFFFFFFFFU, "all bits"); 295fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // static_assert(helper::topBits<u32>(33) == 0xFFFFFFFFU, ""); // should OVERFLOW 296fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 297fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::topBits<u8>(0) == 0U, "top 0 bit"); 298fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::topBits<u8>(1) == 0x80U, "top 1 bit"); 299fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::topBits<u8>(2) == 0xC0U, "top 2 bit"); 300fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::topBits<u8>(8) == 0xFFU, "all bits"); 301fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // static_assert(helper::topBits<u8>(9) == 0xFFU, ""); // should OVERFLOW 302fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 303fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // getShift(mask, base, shared, base-shift, base-effective) 304fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0u, 0u, 0u, 0, 0u) == 0, "no flag require no shift"); 305fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0u, 0u, 1u, 0, 0u) == -1, 306fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "shared must be within mask and base mask"); 307fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0u, 1u, 1u, 0, 1u) == -1, "shared must be within mask"); 308fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0u, 1u, 0u, 0, 1u) == 0, 309fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "no flags require no shift even with base mask"); 310fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0u, 1u, 0u, 1, 2u) == 0, 311fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "no flags require no shift even with shifted base mask"); 312fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(1u, 0u, 0u, 0, 0u) == 0, "no base mask requires no shift"); 313fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(1u, 1u, 0u, 0, 1u) == 1, 314fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "overlapping mask and basemask requires shift"); 315fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(1u, 1u, 0u, 0, 1u) == 1, 316fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "overlapping mask and basemask requires shift"); 317fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(1u, 1u, 1u, 0, 1u) == 0, 318fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "shared mask requires using base shift"); 319fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(1u, 1u, 1u, 1, 2u) == 1, 320fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "shared mask requires using base shift"); 321fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(3u, 5u, 1u, 0, 5u) == 0, 322fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "mask and basemask that overlap only in shared region requires no shift"); 323fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(3u, 7u, 1u, 0, 7u) == -1, 324fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "mask and basemask must not overlap in more than shared region"); 325fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(1u, 0u, 1u, 0, 0u) == -1, "shared must be within base mask"); 326fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 327fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0u, 1u, 0u, 1, 1u) == -2, "effective mask must cover base mask"); 328fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0u, 5u, 0u, 1, 2u) == -2, "effective mask must cover base mask"); 329fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0u, 5u, 0u, 1, 10u) == 0, ""); 330fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0u, 5u, 0u, 1, 31u) == 0, 331fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "effective mask can be larger than base mask"); 332fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 333fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x800Fu, 0x800Fu, 0x800Fu, 0, 0x800Fu) == 0, 334fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x800F << 0) & 0x800F == 0x800F"); 335fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x800Fu, 0x800Fu, 0x800Fu, 16, 0x800F0000u) == 16, 336fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x800F << 0) & 0x800F == 0x800F"); 337fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x1800Fu, 0x800Fu, 0x800Fu, 0, 0x800Fu) == 0, 338fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x1800F << 0) & 0x800F == 0x800F"); 339fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x1800Fu, 0x800Fu, 0x800Fu, 16, 0x800F0000u) == -1, 340fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x1800F << 16) overflows"); 341fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 342fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // verify that when not sharing masks, effective mask makes the difference 343fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x800Fu, 0u, 0u, 0, 0x800Fu) == 4, 344fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x800F << 4) & 0x800F == 0"); 345fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x800Fu, 0x2u, 0u, 0, 0x8002u) == 2, 346fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x800F << 2) & 0x8002 == 0"); 347fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x800Fu, 0x1u, 0u, 15, 0x8001u) == 1, 348fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x800F << 1) & 0x8001 == 0"); 349fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x800Fu, 0x800Fu, 0u, 16, 0x800F0000u) == 0, 350fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "0x800F & 0x800F0000 == 0"); 351fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x800Fu, 0x800F8000u, 0u, 0, 0x800F8000u) == 5, 352fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x800F << 5) & 0x800F8000 == 0"); 353fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x800Fu, 0xF0000u, 0u, 0, 0x800F8000u) == 5, 354fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x800F << 5) & 0x800F8000 == 0"); 355fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x800Fu, 0x1Fu, 0u, 15, 0x800F8000u) == 5, 356fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0x800F << 5) & 0x800F8000 == 0"); 357fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0xFFu, 0x80808080u, 0u, 0, 0x80808080u) == -1, 358fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "0xFF always overlaps with 0x80808080"); 359fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0xFFu, 0x10001000u, 0u, 3, 0x80808080u) == -1, 360fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "0xFF always overlaps with 0x80808080"); 361fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0xFFu, 0x80808040u, 0u, 0, 0x80808040u) == 7, 362fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "(0xFF << 7) & 0x 80808040 == 0"); 363fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 364fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // verify min_shift (mask must be positive or no shift can be required) 365fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0xFF, 0x40808040, 0, 0, 0x40808040) == 7, ""); 366fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift((i32)0x800000FF, 0x40808040, 0, 0, 0x40808040) == -1, ""); 367fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0x100000FF, 0x40808040, 0, 0, 0x40808040) == -1, ""); 368fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift(0xFF, (i32)0x80808040, 0, 0, (i32)0x80808040) == 7, ""); 369fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift((i32)0x80007F80, 0x40808040, 0, 0, 0x40808040) == 0, ""); 370fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 371fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // shared mask can also be negative (but not shift can be required) 372fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift((i32)0x80007F80, (i32)0xC0808040, (i32)0x80000000, 373fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 0, (i32)0xC0808040) == 0, ""); 374fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift((i32)0x80007F80, (i32)0xC0808040, (i32)0xC0000000, 375fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 0, (i32)0xC0808040) == -1, ""); 376fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::getShift((i32)0x80007F80, (i32)0x60404020, (i32)0x60000000, 377fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 1, (i32)0xC0808040) == -1, ""); 378fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 379fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // min_shift 380fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32, u32, 0u> i32_0_0; 381fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32, u32, 1u> i32_1_0; 382fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32, u32, 1u, 0u, 1> i32_1_1; 383fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 384fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // this is a wrapper over getShift, so same test cases apply when T is flagged 385fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_0_0, u32, 0u, 0u>::value == 0, ""); 386fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_0_0, u32, 0u, 1u>::value == -1, ""); 387fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_1_0, u32, 0u, 1u>::value == -1, ""); 388fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_1_0, u32, 0u, 0u>::value == 0, ""); 389fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_0_0, u32, 1u, 0u>::value == 0, ""); 390fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_1_0, u32, 1u, 0u>::value == 1, ""); 391fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_1_0, u32, 1u, 1u>::value == 0, ""); 392fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_1_1, u32, 1u, 1u>::value == 1, ""); 393fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_1_1, u32, 3u, 0u>::value == 2, ""); 394fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, u32, 5u>, u32, 3u, 1u>::value == 0, ""); 395fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, u32, 7u>, u32, 3u, 1u>::value == -1, ""); 396fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_0_0, u32, 1u, 1u>::value == -1, ""); 397fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 398fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_800f_0, u32, 0x800Fu, 0u>::value == 4, ""); 399fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_800f_4, u32, 0x1800Fu, 0x800Fu>::value == 4, ""); 400fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32_800f_4, u32, 0x800Fu, 0u>::value == 0, ""); 401fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, u32, 0x8002u>, u32, 0x800Fu, 0u>::value == 2, ""); 402fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, u32, 0x8001u>, u32, 0x800Fu, 0u>::value == 1, ""); 403fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert( 404fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar helper::min_shift<Flagged<i32, u32, 0x800Fu, 0u, 16>, u32, 0x800Fu, 0u>::value == 0, ""); 405fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert( 406fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar helper::min_shift<Flagged<i32, u32, 0x800F8000u>, u32, 0x800Fu, 0u>::value == 5, ""); 407fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert( 408fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar helper::min_shift<Flagged<i32, u32, 0x80808080u>, u32, 0xFFu, 0u>::value == -1, ""); 409fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert( 410fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar helper::min_shift<Flagged<i32, u32, 0x80808040u>, u32, 0xFFu, 0u>::value == 7, ""); 411fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 412fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // for min_shift, non-tagged type behaves as if having base mask of 0 413fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32, u32, 0u, 0u>::value == 0, ""); 414fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<u32, u32, 0u, 0u>::value == 0, ""); 415fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32, u32, 0u, 0u>::value == 0, ""); 416fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32, u32, 0u, 1u>::value == -1, ""); 417fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32, u32, 1u, 0u>::value == 0, ""); 418fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<i32, u32, 1u, 1u>::value == -1, ""); 419fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 420fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // verify min_shift (mask must be positive or no shift can be required) 421fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, i32, 0x40808040>, i32, 0xFF, 0>::value == 7, ""); 422fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, i32, 0x40808040>, 423fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, (i32)0x800000FF, 0>::value == -1, ""); 424fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, i32, 0x40808040>, 425fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, 0x100000FF, 0>::value == -1, ""); 426fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, i32, (i32)0x80808040>, 427fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, 0xFF, 0>::value == 7, ""); 428fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, i32, 0x40808040>, 429fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, (i32)0x80007F80, 0>::value == 0, ""); 430fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 431fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, i32, (i32)0x80808040>, 432fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, (i32)0x80007F80, (i32)0x80000000>::value == 0, ""); 433fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, i32, (i32)0xC0808040>, 434fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, (i32)0x80007F80, (i32)0xC0000000>::value == -1, ""); 435fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // note: cannot create a flagged type with signed flag and shift 436fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // static_assert(helper::min_shift<Flagged<i32, i32, (i32)0x60404020, 0, 1>, 437fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // i32, (i32)0x40003FC0, (i32)0x40000000>::value == -1, ""); 438fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 439fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32, u32, 0x800F /* mask */, 0 /* shared mask */, 16 /* shift */> i32_800f_16; 440fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert_equals(sizeof(i32_800f_16), sizeof(i32_800f_0), ""); 441fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // shifted mask overflows! 442fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // typedef Flagged<i32, u32, 0x800F /* mask */, 0 /* shared mask */, 17 /* shift */> i32_800f_17; 443fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // static_assert(sizeof(i32_800f_17) == sizeof(i32_800f_0), ""); 444fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32, i32, 0x800F /* mask */, 0 /* shared mask */, 15 /* shift */> i32_800f_15i; 445fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert_equals(sizeof(i32_800f_15i), sizeof(i32_800f_0), ""); 446fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // shifted mask overflows! 447fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // typedef Flagged<i32, i32, 0x800F /* mask */, 0 /* shared mask */, 16 /* shift */> i32_800f_16i; 448fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // static_assert(sizeof(i32_800f_16i) == sizeof(i32_800f_0), ""); 449fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 450fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // canCombine(mask, base, shared, shift, base-shift, base-effective) 451fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0u, 0u, 0u, 0, 0, 0u), "using no mask is valid"); 452fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0u, 0u, 0u, 0, 0, 0u), ""); 453fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0u, 0u, 0u, 4, 0, 0u), ""); 454fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0u, 0u, 1u, 0, 0, 0u), 455fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "shared mask must be the overlap of masks"); 456fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(1u, 0u, 0u, 0, 0, 0u), ""); 457fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(1u, 0u, 0u, 4, 0, 0u), ""); 458fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(3u, 5u, 1u, 0, 0, 5u), ""); 459fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(3u, 3u, 3u, 1, 0, 3u), "shift must match when sharing mask"); 460fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(3u, 3u, 3u, 1, 1, 6u), ""); 461fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(3u, 3u, 3u, 1, 2, 12u), "shift must match when sharing mask"); 462fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(3u, 7u, 1u, 0, 0, 7u), ""); 463fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(1u, 0u, 1u, 0, 0, 0u), ""); 464fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 465fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0u, 1u, 1u, 0, 0, 1u), 466fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "shared mask must be the overlap of masks"); 467fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0u, 1u, 0u, 0, 0, 1u), ""); 468fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0u, 1u, 0u, 4, 0, 1u), ""); 469fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(1u, 1u, 0u, 1, 0, 1u), ""); 470fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(1u, 1u, 0u, 0, 0, 1u), ""); 471fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(1u, 1u, 0u, 1, 0, 1u), ""); 472fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(1u, 1u, 1u, 0, 0, 1u), ""); 473fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(1u, 1u, 1u, 1, 0, 1u), "shift must match when sharing mask"); 474fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 475fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0x800Fu, 0x800Fu, 0u, 4, 0, 0x800Fu), ""); 476fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0x800Fu, 0x800Fu, 0u, 1, 0, 0x800Fu), ""); 477fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0x800Fu, 0x8002u, 0u, 2, 0, 0x8002u), ""); 478fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0x800Fu, 0x8001u, 0u, 1, 0, 0x8001u), ""); 479fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0x800Fu, 0x800Fu, 0u, 0, 16, 0x800F0000u), ""); 480fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0x800Fu, 0x800Fu, 0x800Fu, 16, 16, 0x800F0000u), ""); 481fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0x1800Fu, 0x800Fu, 0u, 0, 16, 0x800F0000u), ""); 482fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0x1800Fu, 0x800Fu, 0x800Fu, 16, 16, 0x800F0000u), ""); 483fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0x800Fu, 0x800F8000u, 0u, 8, 0, 0x800F8000u), ""); 484fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0xFFu, 0x80808080u, 0u, -1, 0, 0x80808080u), ""); 485fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0xFFu, 0x80808040u, 0u, 7, 0, 0x80808040u), ""); 486fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0xFFu, 0x8000u, 0u, 7, 0, 0x80808040u), ""); 487fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0xFFu, 0x101u, 0u, 7, 15, 0x80808040u), ""); 488fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 489fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // can combine signed-flagged types only if mask is positive or no shift is required 490fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0xFF, 0x40808040, 0, 0, 0, 0x40808040), ""); 491fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0xFF, 0x40808040, 0, 7, 0, 0x40808040), ""); 492fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine((i32)0x800000FF, 0x40808040, 0, 0, 0, 0x40808040), ""); 493fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine((i32)0x800000FF, 0x40808040, 0, 7, 0, 0x40808040), ""); 494fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0x100000FF, 0x40808040, 0, 0, 0, 0x40808040), ""); 495fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0x100000FF, 0x40808040, 0, 7, 0, 0x40808040), ""); 496fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine(0xFF, (i32)0x80808040, 0, 0, 0, (i32)0x80808040), ""); 497fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine(0xFF, (i32)0x80808040, 0, 7, 0, (i32)0x80808040), ""); 498fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine((i32)0x80007F80, 0x40808040, 0, 0, 0, 0x40808040), ""); 499fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 500fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::canCombine((i32)0x80007F80, (i32)0x80808040, (i32)0x80000000, 0, 0, (i32)0x80808040), ""); 501fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine((i32)0xC0007F80, (i32)0x80808040, (i32)0xC0000000, 0, 0, (i32)0x80808040), ""); 502fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine((i32)0x80007F80, (i32)0x80808040, (i32)0x80000000, 1, 0, (i32)0x80808040), ""); 503fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::canCombine((i32)0xC0007F80, (i32)0x80808040, (i32)0xC0000000, 1, 0, (i32)0x80808040), ""); 504fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 505fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // can_combine<T, Flag, MASK, [SHARED_MASK], [SHIFT] 506fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_0_0, u32, 0u>::value, ""); 507fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_0_0, u32, 0u, 0u>::value, ""); 508fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_0_0, u32, 0u, 0u, 4>::value, ""); 509fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32_0_0, u32, 0u, 1u>::value, ""); 510fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_0_0, u32, 1u, 0u>::value, ""); 511fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_0_0, u32, 1u, 0u, 4>::value, ""); 512fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32_0_0, u32, 1u, 1u>::value, ""); 513fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 514fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32_1_0, u32, 0u, 1u>::value, ""); 515fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_1_0, u32, 0u, 0u>::value, ""); 516fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_1_0, u32, 0u, 0u, 4>::value, ""); 517fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_1_0, u32, 1u, 0u>::value, ""); 518fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32_1_0, u32, 1u, 0u, 0>::value, ""); 519fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_1_0, u32, 1u, 0u, 1>::value, ""); 520fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_1_0, u32, 1u, 1u>::value, ""); 521fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_1_0, u32, 1u, 1u, 0>::value, ""); 522fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32_1_0, u32, 1u, 1u, 1>::value, 523fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar "shouldn't be able to use SHIFT with SHARED_MASK"); 524fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 525fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_800f_0, u32, 0x800Fu, 0u, 4>::value, ""); 526fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32_800f_0, u32, 0x800Fu, 0u, 1>::value, ""); 527fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<i32_800f_0, u32, 0x800Fu, 0u>::value, ""); 528fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, u32, 0x8002u>, u32, 0x800Fu, 0u>::value, ""); 529fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, u32, 0x8001u>, u32, 0x800Fu, 0u>::value, ""); 530fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, u32, 0x800F0000u>, u32, 0x800Fu, 0u>::value, ""); 531fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, u32, 0x800F8000u>, u32, 0x800Fu, 0u>::value, ""); 532fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<Flagged<i32, u32, 0x80808080u>, u32, 0xFFu, 0u>::value, ""); 533fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, u32, 0x80808040u>, u32, 0xFFu, 0u>::value, ""); 534fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 535fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // can combine signed-flagged types only if mask is positive or no shift is required 536fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, i32, 0x40808040>, i32, 0xFF, 0>::value, ""); 537fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<Flagged<i32, i32, 0x40808040>, 538fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, (i32)0x800000FF, 0>::value, ""); 539fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<Flagged<i32, i32, 0x40808040>, 540fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, 0x100000FF, 0>::value, ""); 541fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, i32, (i32)0x80808040>, i32, 0xFF, 0>::value, ""); 542fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, i32, 0x40808040>, 543fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, (i32)0x80007F80, 0>::value, ""); 544fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 545fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, i32, (i32)0x80808040>, 546fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, (i32)0x80007F80, (i32)0x80000000>::value, ""); 547fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<Flagged<i32, i32, (i32)0xC0808040>, 548fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32, (i32)0x80007F80, (i32)0xC0000000>::value, ""); 549fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 550fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::min_shift<Flagged<i32, FLAG, (FLAG)0x80808040>, 551fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar FLAG, (FLAG)0x80007F80, (FLAG)0x80000000>::value == 0, ""); 552fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(helper::can_combine<Flagged<i32, FLAG, (FLAG)0x80808040>, 553fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar FLAG, (FLAG)0x80007F80, (FLAG)0x80000000>::value, ""); 554fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 555fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // cannot combine non-tagged types 556fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32, u32, 0u, 0u>::value, ""); 557fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<u32, u32, 0u, 0u>::value, ""); 558fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32, u32, 0u, 0u>::value, ""); 559fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32, u32, 0u, 1u>::value, ""); 560fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32, u32, 1u, 0u>::value, ""); 561fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!helper::can_combine<i32, u32, 1u, 1u>::value, ""); 562fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 563fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32_800f_0, u32, 0x800F /* mask */, 0 /* shared mask */> i32_800f_800f; 564fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_800f::sFlagMask == 0x800F, ""); 565fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_800f::sFlagShift == 4, ""); 566fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_800f::sEffectiveMask == 0x880FF, ""); 567fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!i32_800f_0::sFlagCombined, ""); 568fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!i32_800f_4::sFlagCombined, ""); 569fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 570fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_800f::sFlagCombined, ""); 571fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert_equals(sizeof(i32_800f_800f), sizeof(i32_800f_0), ""); 572fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 573fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32_800f_0, u32, 0x1FFFF /* mask */> i32_800f_1ffff; 574fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_1ffff::sFlagMask == 0x1FFFF, ""); 575fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_1ffff::sFlagShift == 0, ""); 576fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_1ffff::sEffectiveMask == 0x1FFFF, ""); 577fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(!i32_800f_1ffff::sFlagCombined, ""); 578fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 579fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // operational tests 580fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32_800f_800f val(0x8000, 0x1234, 56); 581fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(val.get().get(), 56); 582fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(val.flags(), 0x8000u); 583fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(val.get().flags(), 0x1234u & 0x800F); 584fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar val.setFlags(0x12345); 585fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(val.flags(), 0x12345u & 0x800F); 586fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(val.get().flags(), 0x1234u & 0x800F); 587fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar val.get().setFlags(0x54321); 588fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(val.flags(), 0x12345u & 0x800F); 589fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(val.get().flags(), 0x54321u & 0x800F); 590fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(val.get().get(), 56); 591fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 592fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<i32_800f_4, u32, 0x800F /* mask */, 0 /* shared mask */> i32_800f_800f_B; 593fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_800f_B::sFlagMask == 0x800F, ""); 594fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_800f_B::sFlagShift == 0, ""); 595fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_800f_800f_B::sEffectiveMask == 0x880FF, ""); 596fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 597fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32_800f_800f_B valB(0x8000, 0x1234, -987); 598fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valB.get().get(), -987); 599fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valB.flags(), 0x8000u); 600fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valB.get().flags(), 0x1234u & 0x800F); 601fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar valB.setFlags(0x12345); 602fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valB.flags(), 0x12345u & 0x800F); 603fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valB.get().flags(), 0x1234u & 0x800F); 604fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar valB.get().setFlags(0x5C321); 605fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valB.flags(), 0x12345u & 0x800F); 606fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valB.get().flags(), 0x5C321u & 0x800F); 607fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valB.get().get(), -987); 608fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 609fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<Flagged<i32, u32, 0xFF>, u32, 0xFF0, 0xF0> i32_ff_ff0; 610fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32_ff_ff0 valC(0xABCD, 0x1234, 101); 611fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valC.get().get(), 101); 612fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valC.flags(), 0xBC0u); 613fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valC.get().flags(), 0xC4u); 614fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar valC.setFlags(0x12345); 615fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valC.flags(), 0x340u); 616fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valC.get().flags(), 0x44u); 617fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar valC.get().setFlags(0x54321); 618fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valC.flags(), 0x320u); 619fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valC.get().flags(), 0x21u); 620fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valC.get().get(), 101); 621fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 622fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar // when combining flags (with no shift), it should work with signed flags 623fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar typedef Flagged<Flagged<i32, FLAG, kMask0>, FLAG, kMask1, kMaskCommon> i32_F_ff_ff0; 624fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar static_assert(i32_F_ff_ff0::sFlagCombined, "flags should be combined"); 625fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 626fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar i32_F_ff_ff0 valD(kFlag1_A, kFlag0_A, 1023); 627fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valD.get().get(), 1023); 628fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valD.flags(), kFlag1_A); 629fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valD.get().flags(), kFlag0_A); 630fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar valD.setFlags(kFlag1_B); 631fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valD.flags(), kFlag1_B); 632fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valD.get().flags(), FLAG(0x0BA)); 633fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar valD.get().setFlags(kFlag0_C); 634fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valD.flags(), FLAG(0xBC0)); 635fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valD.get().flags(), kFlag0_C); 636fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar EXPECT_EQ(valD.get().get(), 1023); 637fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar} 638fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar 639fba972f9d7f87c47ac0820b7f99420acc7e5dc36Lajos Molnar} // namespace android 640