28 #ifndef FST_SPARSE_TUPLE_WEIGHT_H_ 29 #define FST_SPARSE_TUPLE_WEIGHT_H_ 43 template <
class W,
class K>
49 template <
class W,
class K =
int>
55 using Pair = std::pair<K, W>;
65 template <
class Iterator>
69 for (
auto it = begin; it != end; ++it)
PushBack(*it);
75 : default_(default_weight),
76 first_(weight == default_weight ? kNoKey : key, weight) {}
90 : default_(weight.default_),
91 first_(std::move(weight.first_)),
92 rest_(std::move(weight.rest_)) {
95 weight.first_ =
Pair(kNoKey, W::NoWeight());
114 std::istream &
Read(std::istream &strm) {
120 std::ostream &
Write(std::ostream &strm)
const {
127 if (
this == &weight)
return *
this;
136 if (
this == &weight)
return *
this;
138 default_ = weight.default_;
139 first_ = std::move(weight.first_);
140 rest_ = std::move(weight.rest_);
143 weight.first_ =
Pair(kNoKey, W::NoWeight());
144 weight.rest_.clear();
151 if (!it.Value().second.Member())
return false;
159 static const std::hash<K> H;
161 h = 5 * h + H(it.Value().first);
162 h = 13 * h + it.Value().second.Hash();
170 weight.
PushBack(it.Value().first, it.Value().second.Quantize(delta));
178 weight.
PushBack(it.Value().first, it.Value().second.Reverse());
183 void Init(
const W &default_value = W::Zero()) {
184 first_ =
Pair(kNoKey, W::NoWeight());
186 default_ = default_value;
191 if (first_.first == kNoKey) {
194 return rest_.size() + 1;
198 inline void PushBack(
const K &key,
const W &weight,
199 bool default_value_check =
true) {
200 PushBack(std::make_pair(key, weight), default_value_check);
203 inline void PushBack(
const Pair &pair,
bool default_value_check =
true) {
204 if (default_value_check && pair.second == default_)
return;
205 if (first_.first == kNoKey) {
208 rest_.push_back(pair);
213 const W &
Value(
const K &key)
const {
216 for (; !iter.
Done() && iter.
Value().first < key; iter.
Next())
continue;
217 return !iter.
Done() && iter.
Value().first == key ? iter.
Value().second
225 SetValueToNonDefault(key, w);
234 void SetValueToNonDefault(
const K &key,
const W &w) {
236 if (first_.first == kNoKey) {
237 first_ =
Pair(key, w);
238 }
else if (key < first_.first) {
239 rest_.push_front(first_);
240 first_ =
Pair(key, w);
241 }
else if (key == first_.first) {
245 std::find_if(rest_.begin(), rest_.end(),
246 [key](
const Pair &p) {
return p.first >= key; });
247 if (i != rest_.end() && i->first == key) {
250 rest_.insert(i,
Pair(key, w));
257 void ClearValue(
const K &key) {
258 if (key == first_.first) {
259 if (!rest_.empty()) {
260 first_ = rest_.front();
265 }
else if (key > first_.first) {
267 std::find_if(rest_.begin(), rest_.end(),
268 [key](
const Pair &p) {
return p.first >= key; });
269 if (i != rest_.end() && i->first == key) {
282 std::list<Pair> rest_;
287 template <
class W,
class K>
292 using iterator =
typename std::list<Pair>::iterator;
295 : first_(weight.first_),
298 iter_(rest_.begin()) {}
304 return iter_ == rest_.end();
308 const Pair &
Value()
const {
return init_ ? first_ : *iter_; }
320 iter_ = rest_.begin();
325 const std::list<Pair> &rest_;
332 template <
class W,
class K,
class M>
336 const M &operator_mapper) {
343 while (!w1_it.
Done() || !w2_it.
Done()) {
344 const auto &k1 = (w1_it.
Done()) ? w2_it.
Value().first : w1_it.
Value().first;
345 const auto &k2 = (w2_it.
Done()) ? w1_it.
Value().first : w2_it.
Value().first;
346 const auto &v1 = (w1_it.
Done()) ? v1_def : w1_it.
Value().second;
347 const auto &v2 = (w2_it.
Done()) ? v2_def : w2_it.
Value().second;
349 result->
PushBack(k1, operator_mapper(k1, v1, v2));
352 }
else if (k1 < k2) {
353 result->
PushBack(k1, operator_mapper(k1, v1, v2_def));
356 result->
PushBack(k2, operator_mapper(k2, v1_def, v2));
362 template <
class W,
class K>
367 if (v1_def != v2_def)
return false;
370 while (!w1_it.
Done() || !w2_it.
Done()) {
371 const auto &k1 = (w1_it.
Done()) ? w2_it.
Value().first : w1_it.
Value().first;
372 const auto &k2 = (w2_it.
Done()) ? w1_it.
Value().first : w2_it.
Value().first;
373 const auto &v1 = (w1_it.
Done()) ? v1_def : w1_it.
Value().second;
374 const auto &v2 = (w2_it.
Done()) ? v2_def : w2_it.
Value().second;
376 if (v1 != v2)
return false;
379 }
else if (k1 < k2) {
380 if (v1 != v2_def)
return false;
383 if (v1_def != v2)
return false;
390 template <
class W,
class K>
396 template <
class W,
class K>
410 template <
class W,
class K>
431 #endif // FST_SPARSE_TUPLE_WEIGHT_H_ void PushBack(const Pair &pair, bool default_value_check=true)
void PushBack(const K &key, const W &weight, bool default_value_check=true)
~SparseTupleWeight() noexcept=default
SparseTupleWeight & operator=(SparseTupleWeight &&weight) noexcept
void Init(const W &default_value=W::Zero())
std::ostream & Write(std::ostream &strm) const
typename Arc::Weight Weight
std::pair< K, typename Arc::Weight > Pair
void SparseTupleWeightMap(SparseTupleWeight< W, K > *result, const SparseTupleWeight< W, K > &w1, const SparseTupleWeight< W, K > &w2, const M &operator_mapper)
static const SparseTupleWeight & Zero()
static const SparseTupleWeight & One()
SparseTupleWeightIterator(const SparseTupleWeight< W, K > &weight)
static const SparseTupleWeight & NoWeight()
const Pair & Value() const
void SetValue(const K &key, const W &w)
std::ostream & WriteType(std::ostream &strm, const T t)
std::istream & operator>>(std::istream &strm, FloatWeightTpl< T > &w)
SparseTupleWeight(Iterator begin, Iterator end)
bool operator!=(const ErrorWeight &, const ErrorWeight &)
SparseTupleWeight(const K &key, const W &weight, const W &default_weight)
void SetDefaultValue(const W &value)
std::ostream & operator<<(std::ostream &strm, const ErrorWeight &)
static constexpr K kNoKey
SparseTupleWeight(const W &weight)
typename SparseTupleWeight< W, K >::Pair Pair
const W & DefaultValue() const
SparseTupleWeight & operator=(const SparseTupleWeight &weight)
SparseTupleWeight(const SparseTupleWeight &weight)
typename std::list< Pair >::const_iterator const_iterator
std::istream & Read(std::istream &strm)
bool ReadElement(T *comp, bool last=false)
const W & Value(const K &key) const
bool operator==(const ErrorWeight &, const ErrorWeight &)
SparseTupleWeight Quantize(float delta=kDelta) const
typename std::list< Pair >::iterator iterator
std::istream & ReadType(std::istream &strm, T *t)
void WriteElement(const T &comp)
SparseTupleWeight(SparseTupleWeight &&weight) noexcept
ReverseWeight Reverse() const