1 /**************************************************************************
2  *
3  * Copyright 2011 Jose Fonseca
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25 
26 /*
27  * Helper code for function name indexed lookup tables.
28  */
29 
30 #pragma once
31 
32 
33 #include <assert.h>
34 #include <string.h>
35 
36 #include <algorithm>
37 #include <iostream>
38 
39 
40 namespace trace {
41 
42 
43 /**
44  * Generic type for (name, value) pairs.
45  */
46 template< class T >
47 struct Entry
48 {
49     const char *name;
50     T value;
51 };
52 
53 
54 /**
55  * Function object which compare entries by name.
56  */
57 template< class T >
58 struct EntryCompare {
59     inline bool
operator ()trace::EntryCompare60     operator() (const Entry<T> & a, const Entry<T> & b) const {
61         return strcmp(a.name, b.name) < 0;
62     }
63 };
64 
65 
66 /**
67  * Lookup the entry with the given name, .
68  *
69  * The entry table must be sorted alphabetically (the same rules used by
70  * strcmp).
71  */
72 template< class T, std::size_t n >
73 inline const T &
entryLookup(const char * name,const Entry<T> (& entries)[n],const T & default_)74 entryLookup(const char *name, const Entry<T> (& entries)[n], const T & default_)
75 {
76     typedef const Entry<T> * ConstIterator;
77 
78     ConstIterator first = &entries[0];
79     ConstIterator last = &entries[n];
80 
81     assert(first != last);
82 
83     Entry<T> reference;
84     reference.name = name;
85 
86     EntryCompare<T> compare;
87 
88 #ifndef NDEBUG
89     for (ConstIterator it = first; it != last; ++it) {
90         ConstIterator next = it + 1;
91         if (next != last && !compare(*it, *next)) {
92             std::cerr << "error: " << it->name << " and " << next->name << " not properly sorted\n";
93             assert(0);
94         }
95     }
96 #endif
97 
98     first = std::lower_bound(first, last, reference, compare);
99 
100     if (first == last || compare(reference, *first)) {
101         return default_;
102     }
103 
104     return first->value;
105 }
106 
107 
108 } /* namespace trace */
109 
110