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