1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 namespace android { 19 20 template <typename T, template <typename> class AbilityType> 21 struct Ability { baseAbility22 T& base() { return static_cast<T&>(*this); } baseAbility23 T const& base() const { return static_cast<T const&>(*this); } 24 }; 25 26 template <typename T> 27 struct Add : Ability<T, Add> { 28 inline T operator+(T const& other) const { return T(this->base().value() + other.value()); } 29 inline T& operator++() { 30 ++this->base().value(); 31 return this->base(); 32 }; 33 inline T operator++(int) { 34 T tmp(this->base()); 35 operator++(); 36 return tmp; 37 }; 38 inline T& operator+=(T const& other) { 39 this->base().value() += other.value(); 40 return this->base(); 41 }; 42 }; 43 44 template <typename T> 45 struct Compare : Ability<T, Compare> { 46 inline bool operator==(T const& other) const { return this->base().value() == other.value(); }; 47 inline bool operator<(T const& other) const { return this->base().value() < other.value(); } 48 inline bool operator<=(T const& other) const { return (*this < other) || (*this == other); } 49 inline bool operator!=(T const& other) const { return !(*this == other); } 50 inline bool operator>=(T const& other) const { return !(*this < other); } 51 inline bool operator>(T const& other) const { return !(*this < other || *this == other); } 52 }; 53 54 template <typename T> 55 struct Hash : Ability<T, Hash> { hashHash56 [[nodiscard]] std::size_t hash() const { 57 return std::hash<typename std::remove_const< 58 typename std::remove_reference<decltype(this->base().value())>::type>::type>{}( 59 this->base().value()); 60 } 61 }; 62 63 template <typename T, typename W, template <typename> class... Ability> 64 struct StrongTyping : Ability<StrongTyping<T, W, Ability...>>... { StrongTypingStrongTyping65 StrongTyping() : mValue(0) {} StrongTypingStrongTyping66 explicit StrongTyping(T const& value) : mValue(value) {} 67 StrongTyping(StrongTyping const&) = default; 68 StrongTyping& operator=(StrongTyping const&) = default; TStrongTyping69 explicit inline operator T() const { return mValue; } valueStrongTyping70 T const& value() const { return mValue; } valueStrongTyping71 T& value() { return mValue; } 72 73 private: 74 T mValue; 75 }; 76 } // namespace android 77 78 namespace std { 79 template <typename T, typename W, template <typename> class... Ability> 80 struct hash<android::StrongTyping<T, W, Ability...>> { 81 std::size_t operator()(android::StrongTyping<T, W, Ability...> const& k) const { 82 return k.hash(); 83 } 84 }; 85 } // namespace std 86