Loading services/surfaceflinger/Scheduler/StrongTyping.h 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * 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. */ #pragma once namespace android { template <typename T, template <typename> class AbilityType> struct Ability { T& base() { return static_cast<T&>(*this); } T const& base() const { return static_cast<T const&>(*this); } }; template <typename T> struct Add : Ability<T, Add> { inline T operator+(T const& other) const { return T(this->base().value() + other.value()); } inline T& operator++() { ++this->base().value(); return this->base(); }; inline T operator++(int) { T tmp(this->base()); operator++(); return tmp; }; inline T& operator+=(T const& other) { this->base().value() += other.value(); return this->base(); }; }; template <typename T> struct Compare : Ability<T, Compare> { inline bool operator==(T const& other) const { return this->base().value() == other.value(); }; inline bool operator<(T const& other) const { return this->base().value() < other.value(); } inline bool operator<=(T const& other) const { return (*this < other) || (*this == other); } inline bool operator!=(T const& other) const { return !(*this == other); } inline bool operator>=(T const& other) const { return !(*this < other); } inline bool operator>(T const& other) const { return !(*this < other || *this == other); } }; template <typename T, typename W, template <typename> class... Ability> struct StrongTyping : Ability<StrongTyping<T, W, Ability...>>... { StrongTyping() : mValue(0) {} explicit StrongTyping(T const& value) : mValue(value) {} StrongTyping(StrongTyping const&) = default; StrongTyping& operator=(StrongTyping const&) = default; inline operator T() const { return mValue; } T const& value() const { return mValue; } T& value() { return mValue; } private: T mValue; }; } // namespace android services/surfaceflinger/tests/unittests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ cc_test { "TimeStatsTest.cpp", "FrameTracerTest.cpp", "TransactionApplicationTest.cpp", "StrongTypingTest.cpp", "mock/DisplayHardware/MockComposer.cpp", "mock/DisplayHardware/MockDisplay.cpp", "mock/DisplayHardware/MockPowerAdvisor.cpp", Loading services/surfaceflinger/tests/unittests/StrongTypingTest.cpp 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * 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. */ #include <gmock/gmock.h> #include <gtest/gtest.h> #include "Scheduler/StrongTyping.h" using namespace testing; namespace android { TEST(StrongTypeTest, comparison) { using SpunkyType = StrongTyping<int, struct SpunkyTypeTag, Compare>; SpunkyType f2(22); SpunkyType f1(10); EXPECT_TRUE(f1 == f1); EXPECT_TRUE(SpunkyType(10) != SpunkyType(11)); EXPECT_FALSE(SpunkyType(31) != SpunkyType(31)); EXPECT_TRUE(SpunkyType(10) < SpunkyType(11)); EXPECT_TRUE(SpunkyType(-1) < SpunkyType(0)); EXPECT_FALSE(SpunkyType(-10) < SpunkyType(-20)); EXPECT_TRUE(SpunkyType(10) <= SpunkyType(11)); EXPECT_TRUE(SpunkyType(10) <= SpunkyType(10)); EXPECT_TRUE(SpunkyType(-10) <= SpunkyType(1)); EXPECT_FALSE(SpunkyType(10) <= SpunkyType(9)); EXPECT_TRUE(SpunkyType(11) >= SpunkyType(11)); EXPECT_TRUE(SpunkyType(12) >= SpunkyType(11)); EXPECT_FALSE(SpunkyType(11) >= SpunkyType(12)); EXPECT_FALSE(SpunkyType(11) > SpunkyType(12)); EXPECT_TRUE(SpunkyType(-11) < SpunkyType(7)); } TEST(StrongTypeTest, addition) { using FunkyType = StrongTyping<int, struct FunkyTypeTag, Compare, Add>; FunkyType f2(22); FunkyType f1(10); EXPECT_THAT(f1 + f2, Eq(FunkyType(32))); EXPECT_THAT(f2 + f1, Eq(FunkyType(32))); EXPECT_THAT(++f1, Eq(11)); EXPECT_THAT(f1, Eq(11)); EXPECT_THAT(f1++, Eq(11)); EXPECT_THAT(f1++, Eq(12)); EXPECT_THAT(f1, Eq(13)); auto f3 = f1; EXPECT_THAT(f1, Eq(f3)); EXPECT_THAT(f1, Lt(f2)); f3 += f1; EXPECT_THAT(f1, Eq(13)); EXPECT_THAT(f3, Eq(26)); } } // namespace android Loading
services/surfaceflinger/Scheduler/StrongTyping.h 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * 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. */ #pragma once namespace android { template <typename T, template <typename> class AbilityType> struct Ability { T& base() { return static_cast<T&>(*this); } T const& base() const { return static_cast<T const&>(*this); } }; template <typename T> struct Add : Ability<T, Add> { inline T operator+(T const& other) const { return T(this->base().value() + other.value()); } inline T& operator++() { ++this->base().value(); return this->base(); }; inline T operator++(int) { T tmp(this->base()); operator++(); return tmp; }; inline T& operator+=(T const& other) { this->base().value() += other.value(); return this->base(); }; }; template <typename T> struct Compare : Ability<T, Compare> { inline bool operator==(T const& other) const { return this->base().value() == other.value(); }; inline bool operator<(T const& other) const { return this->base().value() < other.value(); } inline bool operator<=(T const& other) const { return (*this < other) || (*this == other); } inline bool operator!=(T const& other) const { return !(*this == other); } inline bool operator>=(T const& other) const { return !(*this < other); } inline bool operator>(T const& other) const { return !(*this < other || *this == other); } }; template <typename T, typename W, template <typename> class... Ability> struct StrongTyping : Ability<StrongTyping<T, W, Ability...>>... { StrongTyping() : mValue(0) {} explicit StrongTyping(T const& value) : mValue(value) {} StrongTyping(StrongTyping const&) = default; StrongTyping& operator=(StrongTyping const&) = default; inline operator T() const { return mValue; } T const& value() const { return mValue; } T& value() { return mValue; } private: T mValue; }; } // namespace android
services/surfaceflinger/tests/unittests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ cc_test { "TimeStatsTest.cpp", "FrameTracerTest.cpp", "TransactionApplicationTest.cpp", "StrongTypingTest.cpp", "mock/DisplayHardware/MockComposer.cpp", "mock/DisplayHardware/MockDisplay.cpp", "mock/DisplayHardware/MockPowerAdvisor.cpp", Loading
services/surfaceflinger/tests/unittests/StrongTypingTest.cpp 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * 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. */ #include <gmock/gmock.h> #include <gtest/gtest.h> #include "Scheduler/StrongTyping.h" using namespace testing; namespace android { TEST(StrongTypeTest, comparison) { using SpunkyType = StrongTyping<int, struct SpunkyTypeTag, Compare>; SpunkyType f2(22); SpunkyType f1(10); EXPECT_TRUE(f1 == f1); EXPECT_TRUE(SpunkyType(10) != SpunkyType(11)); EXPECT_FALSE(SpunkyType(31) != SpunkyType(31)); EXPECT_TRUE(SpunkyType(10) < SpunkyType(11)); EXPECT_TRUE(SpunkyType(-1) < SpunkyType(0)); EXPECT_FALSE(SpunkyType(-10) < SpunkyType(-20)); EXPECT_TRUE(SpunkyType(10) <= SpunkyType(11)); EXPECT_TRUE(SpunkyType(10) <= SpunkyType(10)); EXPECT_TRUE(SpunkyType(-10) <= SpunkyType(1)); EXPECT_FALSE(SpunkyType(10) <= SpunkyType(9)); EXPECT_TRUE(SpunkyType(11) >= SpunkyType(11)); EXPECT_TRUE(SpunkyType(12) >= SpunkyType(11)); EXPECT_FALSE(SpunkyType(11) >= SpunkyType(12)); EXPECT_FALSE(SpunkyType(11) > SpunkyType(12)); EXPECT_TRUE(SpunkyType(-11) < SpunkyType(7)); } TEST(StrongTypeTest, addition) { using FunkyType = StrongTyping<int, struct FunkyTypeTag, Compare, Add>; FunkyType f2(22); FunkyType f1(10); EXPECT_THAT(f1 + f2, Eq(FunkyType(32))); EXPECT_THAT(f2 + f1, Eq(FunkyType(32))); EXPECT_THAT(++f1, Eq(11)); EXPECT_THAT(f1, Eq(11)); EXPECT_THAT(f1++, Eq(11)); EXPECT_THAT(f1++, Eq(12)); EXPECT_THAT(f1, Eq(13)); auto f3 = f1; EXPECT_THAT(f1, Eq(f3)); EXPECT_THAT(f1, Lt(f2)); f3 += f1; EXPECT_THAT(f1, Eq(13)); EXPECT_THAT(f3, Eq(26)); } } // namespace android