1 /*
2  * Copyright (C) 2020 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 #ifndef ANDROID_XSDC_SUPPORT_H
18 #define ANDROID_XSDC_SUPPORT_H
19 
20 #include <iterator>
21 #include <type_traits>
22 
23 namespace android {
24 
25 namespace details {
26 // Never instantiated. Used as a placeholder for template variables.
27 template <typename T>
28 struct xsdc_invalid_type;
29 
30 // XSDC generates specializations of this for enums. See xsdc_enum_range.
31 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
32 constexpr xsdc_invalid_type<T> xsdc_enum_values;
33 }  // namespace details
34 
35 /**
36  * Every XSDC generated enum supports this function.
37  * E.x.: for (const auto v : xsdc_enum_range<Enum>()) { ... }
38  */
39 template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
40 struct xsdc_enum_range {
41     // Container-like associated type.
42     using value_type = T;
43 
beginxsdc_enum_range44     constexpr auto begin() const { return std::begin(details::xsdc_enum_values<T>); }
cbeginxsdc_enum_range45     constexpr auto cbegin() const { return begin(); }
rbeginxsdc_enum_range46     constexpr auto rbegin() const { return std::rbegin(details::xsdc_enum_values<T>); }
crbeginxsdc_enum_range47     constexpr auto crbegin() const { return rbegin(); }
endxsdc_enum_range48     constexpr auto end() const { return std::end(details::xsdc_enum_values<T>); }
cendxsdc_enum_range49     constexpr auto cend() const { return end(); }
rendxsdc_enum_range50     constexpr auto rend() const { return std::rend(details::xsdc_enum_values<T>); }
crendxsdc_enum_range51     constexpr auto crend() const { return rend(); }
52 };
53 
54 }  // namespace android
55 
56 #endif  // ANDROID_XSDC_SUPPORT_H
57