File indexing completed on 2024-04-28 05:46:50
0001 /***************************************************************************** 0002 * Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU Lesser General Public License as * 0006 * published by the Free Software Foundation; either version 2.1 of the * 0007 * License, or (at your option) version 3, or any later version accepted * 0008 * by the membership of KDE e.V. (or its successor approved by the * 0009 * membership of KDE e.V.), which shall act as a proxy defined in * 0010 * Section 6 of version 3 of the license. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 0015 * Lesser General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU Lesser General Public * 0018 * License along with this library. If not, * 0019 * see <http://www.gnu.org/licenses/>. * 0020 *****************************************************************************/ 0021 0022 #ifndef _QTC_UTILS_MAP_H_ 0023 #define _QTC_UTILS_MAP_H_ 0024 0025 #include "utils.h" 0026 0027 #include <vector> 0028 #include <algorithm> 0029 0030 namespace QtCurve { 0031 0032 // C++14 integer sequence 0033 template<int...> 0034 struct seq { 0035 }; 0036 0037 template<int N, int... S> 0038 struct gens : gens<N - 1, N - 1, S...> { 0039 }; 0040 0041 template<int ...S> 0042 struct gens<0, S...> { 0043 typedef seq<S...> type; 0044 }; 0045 0046 template<int N> 0047 using gens_t = typename gens<N>::type; 0048 0049 template<typename Val=int, bool case_sens=true> 0050 class StrMap : std::vector<std::pair<const char*, Val> > { 0051 typedef std::pair<const char*, Val> pair_type; 0052 static int 0053 strcmp_func(const char *a, const char *b) 0054 { 0055 if (case_sens) { 0056 return strcmp(a, b); 0057 } else { 0058 return strcasecmp(a, b); 0059 } 0060 } 0061 template<typename... Ts, int ...S> 0062 StrMap(seq<S...>, Ts&&... ts) 0063 : StrMap{{ts, Val(S)}...} 0064 { 0065 } 0066 public: 0067 StrMap(std::initializer_list<pair_type> &&ts) 0068 : std::vector<pair_type>(std::move(ts)) 0069 { 0070 std::sort(this->begin(), this->end(), 0071 [] (const pair_type &a, const pair_type &b) { 0072 return strcmp_func(a.first, b.first) < 0; 0073 }); 0074 } 0075 template<typename... Ts> 0076 StrMap(Ts&&... ts) 0077 : StrMap(gens_t<sizeof...(Ts)>(), std::forward<Ts>(ts)...) 0078 { 0079 } 0080 Val 0081 search(const char *key, Val def=Val(-1), bool *is_def=nullptr) const 0082 { 0083 QTC_RET_IF_FAIL(key, def); 0084 auto lower_it = std::lower_bound( 0085 this->begin(), this->end(), key, [] (const pair_type &a, 0086 const char *key) { 0087 return strcmp_func(a.first, key) < 0; 0088 }); 0089 if (lower_it == this->end() || 0090 strcmp_func(lower_it->first, key) != 0) { 0091 qtcAssign(is_def, true); 0092 return def; 0093 } 0094 qtcAssign(is_def, false); 0095 return lower_it->second; 0096 } 0097 }; 0098 0099 } 0100 0101 #endif