/src/aspell/common/enumeration.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2001 |
2 | | // Kevin Atkinson |
3 | | // |
4 | | // Permission to use, copy, modify, distribute and sell this software |
5 | | // and its documentation for any purpose is hereby granted without |
6 | | // fee, provided that the above copyright notice appear in all copies |
7 | | // and that both that copyright notice and this permission notice |
8 | | // appear in supporting documentation. Kevin Atkinson makes no |
9 | | // representations about the suitability of this software for any |
10 | | // purpose. It is provided "as is" without express or implied |
11 | | // warranty. |
12 | | |
13 | | #ifndef __autil_enumeration__ |
14 | | #define __autil_enumeration__ |
15 | | |
16 | | #include "clone_ptr-t.hpp" |
17 | | |
18 | | // An enumeration is an efficient way to iterate through elements much |
19 | | // like a forward iterator. The at_end method is a convince method |
20 | | // as enumerations will return a null pointer or some other sort of |
21 | | // special end state when they are at the end. |
22 | | // Unlike an iterator iterating through x elements on a list can be |
23 | | // done in x function calls while an iterator will require 3*x. |
24 | | // function calls. |
25 | | // Example of emulator usage |
26 | | // const char * word; |
27 | | // while ( (word = elements->next()) != 0) { // one function call |
28 | | // cout << word << endl; |
29 | | // } |
30 | | // And an iterator |
31 | | // iterator i = container->begin(); |
32 | | // iterator end = container->end(); |
33 | | // while (i != end) { // comparison, one function call |
34 | | // cout << *i << endl; // deref, total of two function calls |
35 | | // ++i; // increment, total of three function calls. |
36 | | // } |
37 | | // Normally all three calls are inline so it doesn't really matter |
38 | | // but when the container type is not visible there are not inline |
39 | | // and probably even virtual. |
40 | | // If you really love iterators you can very easily wrap an enumeration |
41 | | // in a forward iterator. |
42 | | |
43 | | namespace acommon { |
44 | | |
45 | | template <typename Val> |
46 | | class Enumeration { |
47 | | public: |
48 | | typedef Val Value; |
49 | | typedef Enumeration Base; |
50 | | virtual Enumeration * clone() const = 0; |
51 | | virtual void assign(const Enumeration *) = 0; |
52 | | virtual Value next() = 0; |
53 | | virtual bool at_end() const = 0; |
54 | 0 | virtual ~Enumeration() {} Unexecuted instantiation: acommon::Enumeration<aspeller::Dictionary*>::~Enumeration() Unexecuted instantiation: acommon::Enumeration<aspeller::WordEntry*>::~Enumeration() |
55 | | }; |
56 | | |
57 | | template <class Parms, class Enum = Enumeration<typename Parms::Value> > |
58 | | // Parms is expected to have the following members: |
59 | | // typename Value |
60 | | // typename Iterator; |
61 | | // bool endf(Iterator) |
62 | | // Value end_state() |
63 | | // Value deref(Iterator) |
64 | | class MakeEnumeration : public Enum { |
65 | | public: |
66 | | typedef typename Parms::Iterator Iterator; |
67 | | typedef typename Parms::Value Value; |
68 | | private: |
69 | | Iterator i_; |
70 | | Parms parms_; |
71 | | public: |
72 | | |
73 | | MakeEnumeration(const Iterator i, const Parms & p = Parms()) |
74 | 13.5k | : i_(i), parms_(p) {} suggest.cpp:acommon::MakeEnumeration<(anonymous namespace)::SuggestionListImpl::Parms, acommon::StringEnumeration>::MakeEnumeration(std::__1::__wrap_iter<(anonymous namespace)::Suggestion const*>, (anonymous namespace)::SuggestionListImpl::Parms const&) Line | Count | Source | 74 | 13.5k | : i_(i), parms_(p) {} |
Unexecuted instantiation: multi_ws.cpp:acommon::MakeEnumeration<(anonymous namespace)::Parms, acommon::Enumeration<aspeller::Dictionary*> >::MakeEnumeration(std::__1::__wrap_iter<aspeller::Dictionary* const*>, (anonymous namespace)::Parms const&) Unexecuted instantiation: writable.cpp:acommon::MakeEnumeration<(anonymous namespace)::ElementsParms, acommon::Enumeration<aspeller::WordEntry*> >::MakeEnumeration(acommon::HT_ConstIterator<char const*>, (anonymous namespace)::ElementsParms const&) |
75 | | |
76 | 0 | Enum * clone() const { |
77 | 0 | return new MakeEnumeration(*this); |
78 | 0 | } Unexecuted instantiation: suggest.cpp:acommon::MakeEnumeration<(anonymous namespace)::SuggestionListImpl::Parms, acommon::StringEnumeration>::clone() const Unexecuted instantiation: multi_ws.cpp:acommon::MakeEnumeration<(anonymous namespace)::Parms, acommon::Enumeration<aspeller::Dictionary*> >::clone() const Unexecuted instantiation: writable.cpp:acommon::MakeEnumeration<(anonymous namespace)::ElementsParms, acommon::Enumeration<aspeller::WordEntry*> >::clone() const |
79 | | |
80 | 0 | void assign (const Enum * other) { |
81 | 0 | *this = *static_cast<const MakeEnumeration *>(other); |
82 | 0 | } Unexecuted instantiation: suggest.cpp:acommon::MakeEnumeration<(anonymous namespace)::SuggestionListImpl::Parms, acommon::StringEnumeration>::assign(acommon::StringEnumeration const*) Unexecuted instantiation: multi_ws.cpp:acommon::MakeEnumeration<(anonymous namespace)::Parms, acommon::Enumeration<aspeller::Dictionary*> >::assign(acommon::Enumeration<aspeller::Dictionary*> const*) Unexecuted instantiation: writable.cpp:acommon::MakeEnumeration<(anonymous namespace)::ElementsParms, acommon::Enumeration<aspeller::WordEntry*> >::assign(acommon::Enumeration<aspeller::WordEntry*> const*) |
83 | | |
84 | 738k | Value next() { |
85 | 738k | if (parms_.endf(i_)) |
86 | 13.5k | return parms_.end_state(); |
87 | 724k | Value temp = parms_.deref(i_); |
88 | 724k | ++i_; |
89 | 724k | return temp; |
90 | 738k | } suggest.cpp:acommon::MakeEnumeration<(anonymous namespace)::SuggestionListImpl::Parms, acommon::StringEnumeration>::next() Line | Count | Source | 84 | 738k | Value next() { | 85 | 738k | if (parms_.endf(i_)) | 86 | 13.5k | return parms_.end_state(); | 87 | 724k | Value temp = parms_.deref(i_); | 88 | 724k | ++i_; | 89 | 724k | return temp; | 90 | 738k | } |
Unexecuted instantiation: multi_ws.cpp:acommon::MakeEnumeration<(anonymous namespace)::Parms, acommon::Enumeration<aspeller::Dictionary*> >::next() Unexecuted instantiation: writable.cpp:acommon::MakeEnumeration<(anonymous namespace)::ElementsParms, acommon::Enumeration<aspeller::WordEntry*> >::next() |
91 | | |
92 | 0 | bool at_end() const { |
93 | 0 | return parms_.endf(i_); |
94 | 0 | } Unexecuted instantiation: suggest.cpp:acommon::MakeEnumeration<(anonymous namespace)::SuggestionListImpl::Parms, acommon::StringEnumeration>::at_end() const Unexecuted instantiation: multi_ws.cpp:acommon::MakeEnumeration<(anonymous namespace)::Parms, acommon::Enumeration<aspeller::Dictionary*> >::at_end() const Unexecuted instantiation: writable.cpp:acommon::MakeEnumeration<(anonymous namespace)::ElementsParms, acommon::Enumeration<aspeller::WordEntry*> >::at_end() const |
95 | | }; |
96 | | |
97 | | template <class Value> |
98 | | struct MakeAlwaysEndEnumerationParms { |
99 | | Value end_state() const {return Value();} |
100 | | }; |
101 | | |
102 | | template <class Value> |
103 | | struct MakeAlwaysEndEnumerationParms<Value *> { |
104 | | Value * end_state() const {return 0;} |
105 | | }; |
106 | | |
107 | | template <class Value> |
108 | | class MakeAlwaysEndEnumeration : public Enumeration<Value> { |
109 | | MakeAlwaysEndEnumerationParms<Value> parms_; |
110 | | public: |
111 | | MakeAlwaysEndEnumeration * clone() const { |
112 | | return new MakeAlwaysEndEnumeration(*this); |
113 | | } |
114 | | void assign(const Enumeration<Value> * that) { |
115 | | *this = *static_cast<const MakeAlwaysEndEnumeration *>(that); |
116 | | } |
117 | | Value next() {return parms_.end_state();} |
118 | | bool at_end() const {return true;} |
119 | | }; |
120 | | } |
121 | | |
122 | | #endif |
123 | | |