#pragma once #include "../base/base.hpp" #include "../base/assert.hpp" #include "../base/buffer_vector.hpp" //#include "../base/object_tracker.hpp" #include "../std/scoped_ptr.hpp" namespace trie { typedef uint32_t TrieChar; // 95 is a good value for the default baseChar, since both small and capital latin letters // are less than +/- 32 from it and thus can fit into supershort edge. // However 0 is used because the first byte is actually language id. static uint32_t const DEFAULT_CHAR = 0; template class Iterator { //dbg::ObjectTracker m_tracker; public: struct Edge { typedef buffer_vector EdgeStrT; EdgeStrT m_str; EdgeValueT m_value; }; buffer_vector m_edge; buffer_vector m_value; virtual ~Iterator() {} virtual Iterator * Clone() const = 0; virtual Iterator * GoToEdge(uint32_t i) const = 0; }; namespace reader { struct EmptyValueReader { typedef unsigned char ValueType; template void operator() (SourceT &, ValueType & value) const { value = 0; } }; template struct FixedSizeValueReader { struct ValueType { unsigned char m_data[N]; }; template void operator() (SourceT & src, ValueType & value) const { src.Read(&value.m_data[0], N); } }; } // namespace trie::reader template void ForEachRef(Iterator const & iter, F & f, StringT const & s) { for (size_t i = 0; i < iter.m_value.size(); ++i) f(s, iter.m_value[i]); for (size_t i = 0; i < iter.m_edge.size(); ++i) { StringT s1(s); s1.insert(s1.end(), iter.m_edge[i].m_str.begin(), iter.m_edge[i].m_str.end()); scoped_ptr > pIter1(iter.GoToEdge(i)); ForEachRef(*pIter1, f, s1); } } } // namespace Trie