C2ParamUtils.h revision 11ca9ffc72a9d7c628353c1a9295d3b23ec51d22
111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/* 211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * Copyright (C) 2016 The Android Open Source Project 311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * 411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License"); 511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * you may not use this file except in compliance with the License. 611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * You may obtain a copy of the License at 711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * 811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * http://www.apache.org/licenses/LICENSE-2.0 911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * 1011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * Unless required by applicable law or agreed to in writing, software 1111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS, 1211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * See the License for the specific language governing permissions and 1411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * limitations under the License. 1511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar */ 1611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 1711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#ifndef C2UTILS_PARAM_UTILS_H_ 1811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#define C2UTILS_PARAM_UTILS_H_ 1911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 2011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#include <C2Param.h> 2111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#include <util/_C2MacroUtils.h> 2211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 2311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#include <iostream> 2411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 2511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/** \file 2611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * Utilities for parameter handling to be used by Codec2 implementations. 2711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar */ 2811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 2911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarnamespace android { 3011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 3111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/// \cond INTERNAL 3211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 3311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/* ---------------------------- UTILITIES FOR ENUMERATION REFLECTION ---------------------------- */ 3411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 3511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/** 3611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * Utility class that allows ignoring enum value assignment (e.g. both '(_C2EnumConst)kValue = x' 3711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar * and '(_C2EnumConst)kValue' will eval to kValue. 3811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar */ 3911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnartemplate<typename T> 4011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarclass _C2EnumConst { 4111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarpublic: 4211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // implicit conversion from T 4311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar inline _C2EnumConst(T value) : _mValue(value) {} 4411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // implicit conversion to T 4511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar inline operator T() { return _mValue; } 4611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // implicit conversion to C2Value::Primitive 4711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar inline operator C2Value::Primitive() { return (T)_mValue; } 4811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // ignore assignment and return T here to avoid implicit conversion to T later 4911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar inline T &operator =(T value __unused) { return _mValue; } 5011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarprivate: 5111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar T _mValue; 5211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar}; 5311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 5411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/// mapper to get name of enum 5511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/// \note this will contain any initialization, which we will remove when converting to lower-case 5611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#define _C2_GET_ENUM_NAME(x, y) #x 5711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/// mapper to get value of enum 5811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#define _C2_GET_ENUM_VALUE(x, type) (_C2EnumConst<type>)x 5911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 6011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/// \endcond 6111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 6211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#define DEFINE_C2_ENUM_VALUE_AUTO_HELPER(name, type, prefix, ...) \ 6311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnartemplate<> C2FieldDescriptor::named_values_type C2FieldDescriptor::namedValuesFor(const name &r __unused) { \ 6411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return C2ParamUtils::sanitizeEnumValues( \ 6511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::vector<C2Value::Primitive> { _C2_MAP(_C2_GET_ENUM_VALUE, type, __VA_ARGS__) }, \ 6611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar { _C2_MAP(_C2_GET_ENUM_NAME, type, __VA_ARGS__) }, \ 6711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar prefix); \ 6811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar} 6911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 7011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#define DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(name, type, names, ...) \ 7111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnartemplate<> C2FieldDescriptor::named_values_type C2FieldDescriptor::namedValuesFor(const name &r __unused) { \ 7211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return C2ParamUtils::customEnumValues( \ 7311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::vector<std::pair<C2StringLiteral, name>> names); \ 7411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar} 7511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 7611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 7711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarclass C2ParamUtils { 7811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarprivate: 7911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar static size_t countLeadingUnderscores(C2StringLiteral a) { 8011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar size_t i = 0; 8111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar while (a[i] == '_') { 8211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar ++i; 8311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 8411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return i; 8511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 8611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 8711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar static size_t countMatching(C2StringLiteral a, const C2String &b) { 8811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar for (size_t i = 0; i < b.size(); ++i) { 8911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (!a[i] || a[i] != b[i]) { 9011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return i; 9111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 9211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 9311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return b.size(); 9411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 9511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 9611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // ABCDef => abc-def 9711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // ABCD2ef => abcd2-ef // 0 9811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // ABCD2Ef => ancd2-ef // -1 9911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // AbcDef => abc-def // -1 10011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // Abc2Def => abc-2def 10111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // Abc2def => abc-2-def 10211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // _Yo => _yo 10311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // _yo => _yo 10411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // C2_yo => c2-yo 10511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // C2__yo => c2-yo 10611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 10711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar static C2String camelCaseToDashed(C2String name) { 10811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar enum { 10911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar kNone = '.', 11011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar kLower = 'a', 11111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar kUpper = 'A', 11211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar kDigit = '1', 11311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar kDash = '-', 11411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar kUnderscore = '_', 11511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } type = kNone; 11611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar size_t word_start = 0; 11711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar for (size_t ix = 0; ix < name.size(); ++ix) { 11811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar /* std::cout << name.substr(0, word_start) << "|" 11911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar << name.substr(word_start, ix - word_start) << "[" 12011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar << name.substr(ix, 1) << "]" << name.substr(ix + 1) 12111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar << ": " << (char)type << std::endl; */ 12211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (isupper(name[ix])) { 12311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (type == kLower) { 12411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar name.insert(ix++, 1, '-'); 12511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar word_start = ix; 12611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 12711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar name[ix] = tolower(name[ix]); 12811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar type = kUpper; 12911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } else if (islower(name[ix])) { 13011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (type == kDigit && ix > 0) { 13111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar name.insert(ix++, 1, '-'); 13211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar word_start = ix; 13311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } else if (type == kUpper && ix > word_start + 1) { 13411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar name.insert(ix++ - 1, 1, '-'); 13511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar word_start = ix - 1; 13611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 13711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar type = kLower; 13811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } else if (isdigit(name[ix])) { 13911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (type == kLower) { 14011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar name.insert(ix++, 1, '-'); 14111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar word_start = ix; 14211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 14311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar type = kDigit; 14411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } else if (name[ix] == '_') { 14511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (type == kDash) { 14611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar name.erase(ix--, 1); 14711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } else if (type != kNone && type != kUnderscore) { 14811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar name[ix] = '-'; 14911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar type = kDash; 15011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar word_start = ix + 1; 15111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } else { 15211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar type = kUnderscore; 15311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar word_start = ix + 1; 15411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 15511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } else { 15611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar name.resize(ix); 15711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 15811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 15911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // std::cout << "=> " << name << std::endl; 16011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return name; 16111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 16211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 16311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar static std::vector<C2String> sanitizeEnumValueNames( 16411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar const std::vector<C2StringLiteral> names, 16511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar C2StringLiteral _prefix = NULL) { 16611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::vector<C2String> sanitizedNames; 16711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar C2String prefix; 16811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar size_t extraUnderscores = 0; 16911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar bool first = true; 17011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (_prefix) { 17111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar extraUnderscores = countLeadingUnderscores(_prefix); 17211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar prefix = _prefix + extraUnderscores; 17311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar first = false; 17411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // std::cout << "prefix:" << prefix << ", underscores:" << extraUnderscores << std::endl; 17511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 17611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 17711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // calculate prefix and minimum leading underscores 17811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar for (C2StringLiteral s : names) { 17911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // std::cout << s << std::endl; 18011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar size_t underscores = countLeadingUnderscores(s); 18111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (first) { 18211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar extraUnderscores = underscores; 18311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar prefix = s + underscores; 18411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar first = false; 18511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } else { 18611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar size_t matching = countMatching( 18711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar s + underscores, 18811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar prefix); 18911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar prefix.resize(matching); 19011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar extraUnderscores = std::min(underscores, extraUnderscores); 19111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 19211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // std::cout << "prefix:" << prefix << ", underscores:" << extraUnderscores << std::endl; 19311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (prefix.size() == 0 && extraUnderscores == 0) { 19411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar break; 19511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 19611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 19711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 19811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar // we swallow the first underscore after upper case prefixes 19911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar bool upperCasePrefix = true; 20011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar for (size_t i = 0; i < prefix.size(); ++i) { 20111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (islower(prefix[i])) { 20211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar upperCasePrefix = false; 20311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar break; 20411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 20511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 20611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 20711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar for (C2StringLiteral s : names) { 20811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar size_t underscores = countLeadingUnderscores(s); 20911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar C2String sanitized = C2String(s, underscores - extraUnderscores); 21011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar sanitized.append(s + prefix.size() + underscores + 21111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar (upperCasePrefix && s[prefix.size() + underscores] == '_')); 21211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar sanitizedNames.push_back(camelCaseToDashed(sanitized)); 21311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 21411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 21511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar for (C2String s : sanitizedNames) { 21611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::cout << s << std::endl; 21711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 21811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 21911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return sanitizedNames; 22011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 22111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 22211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar friend class C2ParamTest_ParamUtilsTest_Test; 22311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 22411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarpublic: 22511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar static std::vector<C2String> getEnumValuesFromString(C2StringLiteral value) { 22611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::vector<C2String> foundNames; 22711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar size_t pos = 0, len = strlen(value); 22811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar do { 22911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar size_t endPos = strcspn(value + pos, " ,=") + pos; 23011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (endPos > pos) { 23111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar foundNames.emplace_back(value + pos, endPos - pos); 23211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 23311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar if (value[endPos] && value[endPos] != ',') { 23411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar endPos += strcspn(value + endPos, ","); 23511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 23611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar pos = strspn(value + endPos, " ,") + endPos; 23711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } while (pos < len); 23811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return foundNames; 23911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 24011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 24111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar template<typename T> 24211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar static C2FieldDescriptor::named_values_type sanitizeEnumValues( 24311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::vector<T> values, 24411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::vector<C2StringLiteral> names, 24511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar C2StringLiteral prefix = NULL) { 24611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar C2FieldDescriptor::named_values_type namedValues; 24711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::vector<C2String> sanitizedNames = sanitizeEnumValueNames(names, prefix); 24811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar for (size_t i = 0; i < values.size() && i < sanitizedNames.size(); ++i) { 24911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar namedValues.emplace_back(sanitizedNames[i], values[i]); 25011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 25111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return namedValues; 25211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 25311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 25411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar template<typename E> 25511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar static C2FieldDescriptor::named_values_type customEnumValues( 25611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::vector<std::pair<C2StringLiteral, E>> items) { 25711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar C2FieldDescriptor::named_values_type namedValues; 25811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar for (auto &item : items) { 25911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar namedValues.emplace_back(item.first, item.second); 26011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 26111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return namedValues; 26211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar } 26311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar}; 26411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 26511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/* ---------------------------- UTILITIES FOR PARAMETER REFLECTION ---------------------------- */ 26611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 26711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/* ======================== UTILITY TEMPLATES FOR PARAMETER REFLECTION ======================== */ 26811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 26911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#if 1 27011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnartemplate<typename... Params> 27111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarclass C2_HIDE _C2Tuple { }; 27211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 27311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos MolnarC2_HIDE 27411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarvoid addC2Params(std::list<const C2FieldDescriptor> &, _C2Tuple<> *) { 27511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar} 27611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 27711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnartemplate<typename T, typename... Params> 27811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos MolnarC2_HIDE 27911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarvoid addC2Params(std::list<const C2FieldDescriptor> &fields, _C2Tuple<T, Params...> *) 28011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar{ 28111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar //C2Param::index_t index = T::baseIndex; 28211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar //(void)index; 28311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar fields.insert(fields.end(), T::fieldList); 28411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar addC2Params(fields, (_C2Tuple<Params...> *)nullptr); 28511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar} 28611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 28711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnartemplate<typename... Params> 28811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos MolnarC2_HIDE 28911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnarstd::list<const C2FieldDescriptor> describeC2Params() { 29011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar std::list<const C2FieldDescriptor> fields; 29111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar addC2Params(fields, (_C2Tuple<Params...> *)nullptr); 29211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar return fields; 29311ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar} 29411ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 29511ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#endif 29611ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 29711ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar/* ---------------------------- UTILITIES FOR ENUMERATION REFLECTION ---------------------------- */ 29811ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 29911ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar} // namespace android 30011ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 30111ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar#endif // C2UTILS_PARAM_UTILS_H_ 30211ca9ffc72a9d7c628353c1a9295d3b23ec51d22Lajos Molnar 303