Используя некоторые неприятные макросы и шаблонную магию, можно получить развернутый двоичный поиск во время компиляции с красивым синтаксисом, но MATCHES ("case") должны быть sorted : fastmatch.h
NEWMATCH
MATCH("asd")
some c++ code
MATCH("bqr")
... the buffer for the match is in _buf
MATCH("zzz")
... user.YOURSTUFF
/*ELSE
optional
*/
ENDMATCH(xy_match)
Это сгенерирует (примерно) функцию bool xy_match(char *&_buf,T &user)
, поэтому она должна быть на внешнем уровне. Назовите это, например с:
xy_match("bqr",youruserdata);
И break
неявны, вы не можете упасть через. Это также не сильно задокументировано, извините. Но вы обнаружите, что есть еще несколько возможностей использования, посмотрите. ПРИМЕЧАНИЕ. Проверено только с g ++.
Обновление C ++ 11:
Lambdas и список инициализаторов делают вещи намного красивее (без макросов!):
#include <utility>
#include <algorithm>
#include <initializer_list>
template <typename KeyType,typename FunPtrType,typename Comp>
void Switch(const KeyType &value,std::initializer_list<std::pair<const KeyType,FunPtrType>> sws,Comp comp) {
typedef std::pair<const KeyType &,FunPtrType> KVT;
auto cmp=[&comp](const KVT &a,const KVT &b){ return comp(a.first,b.first); };
auto val=KVT(value,FunPtrType());
auto r=std::lower_bound(sws.begin(),sws.end(),val,cmp);
if ( (r!=sws.end())&&(!cmp(val,*r)) ) {
r->second();
} // else: not found
}
#include <string.h>
#include <stdio.h>
int main()
{
Switch<const char *,void (*)()>("ger",{ // sorted:
{"asdf",[]{ printf("0\n"); }},
{"bde",[]{ printf("1\n"); }},
{"ger",[]{ printf("2\n"); }}
},[](const char *a,const char *b){ return strcmp(a,b)<0;});
return 0;
}
Это идея. Более полную реализацию можно найти здесь: switch.hpp .
Обновление 2016: время компиляции
Мой новый взгляд на эту проблему использует расширенное метапрограммирование c ++ 11 для
генерировать search-trie во время компиляции.
В отличие от предыдущих подходов, это будет обрабатывать несортированные
case-ветки / строки просто отлично; они должны быть только строковыми литералами.
G ++ также позволяет использовать constexpr для них, но не лязг (по состоянию на HEAD 3.9.0 / trunk 274233).
В каждом узле trie используется оператор switch для использования расширенного генератора кода компилятора.
Полная версия доступна на github: Smilingthax / Cttrie .