00001 #pragma once
00002
00003 #include <limits>
00004 #include <sstream>
00005 #include <vector>
00006
00007 #include <boost/unordered_map.hpp>
00008
00009 #include "exception.h"
00010
00011 namespace MosesTraining {
00012 namespace Syntax {
00013
00014
00015
00016
00017 template<typename T, typename I=size_t>
00018 class NumberedSet {
00019 private:
00020 typedef boost::unordered_map<T, I> ElementToIdMap;
00021 typedef std::vector<const T *> IdToElementMap;
00022
00023 public:
00024 typedef I IdType;
00025 typedef typename IdToElementMap::const_iterator const_iterator;
00026
00027 NumberedSet() {}
00028
00029 const_iterator begin() const { return id_to_element_.begin(); }
00030 const_iterator end() const { return id_to_element_.end(); }
00031
00032
00033 static I NullId() { return std::numeric_limits<I>::max(); }
00034
00035 bool IsEmpty() const { return id_to_element_.empty(); }
00036 size_t Size() const { return id_to_element_.size(); }
00037
00038
00039 I Insert(const T &);
00040
00041
00042 I Lookup(const T &) const;
00043
00044
00045
00046
00047 template<typename CompatibleKey, typename CompatibleHash,
00048 typename CompatiblePredicate>
00049 I Lookup(const CompatibleKey &, const CompatibleHash &,
00050 const CompatiblePredicate &) const;
00051
00052
00053 const T &Lookup(I) const;
00054
00055 void Clear();
00056
00057 private:
00058 ElementToIdMap element_to_id_;
00059 IdToElementMap id_to_element_;
00060 };
00061
00062 template<typename T, typename I>
00063 I NumberedSet<T, I>::Lookup(const T &s) const {
00064 typename ElementToIdMap::const_iterator p = element_to_id_.find(s);
00065 return (p == element_to_id_.end()) ? NullId() : p->second;
00066 }
00067
00068 template<typename T, typename I>
00069 template<typename CompatibleKey, typename CompatibleHash,
00070 typename CompatiblePredicate>
00071 I NumberedSet<T, I>::Lookup(const CompatibleKey &key,
00072 const CompatibleHash &hash,
00073 const CompatiblePredicate &pred) const {
00074 typename ElementToIdMap::const_iterator p =
00075 element_to_id_.find(key, hash, pred);
00076 return (p == element_to_id_.end()) ? NullId() : p->second;
00077 }
00078
00079 template<typename T, typename I>
00080 const T &NumberedSet<T, I>::Lookup(I id) const {
00081
00082
00083 if (id >= id_to_element_.size()) {
00084 std::ostringstream msg;
00085 msg << "Value not found: " << id;
00086 throw Exception(msg.str());
00087 }
00088 return *(id_to_element_[id]);
00089 }
00090
00091 template<typename T, typename I>
00092 I NumberedSet<T, I>::Insert(const T &x) {
00093 std::pair<T, I> value(x, id_to_element_.size());
00094 std::pair<typename ElementToIdMap::iterator, bool> result =
00095 element_to_id_.insert(value);
00096 if (result.second) {
00097
00098 id_to_element_.push_back(&result.first->first);
00099 }
00100 return result.first->second;
00101 }
00102
00103 template<typename T, typename I>
00104 void NumberedSet<T, I>::Clear() {
00105 element_to_id_.clear();
00106 id_to_element_.clear();
00107 }
00108
00109 }
00110 }