The Battle for Wesnoth  1.17.4+dev
recall_list_manager.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2022
3  by Chris Beck <render787@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "recall_list_manager.hpp"
17 #include "units/unit.hpp"
18 #include "units/ptr.hpp"
19 
20 #include <algorithm>
21 #include <string>
22 #include <vector>
23 
24 #include <functional>
25 
26 /**
27  * Used to find units in vectors by their ID.
28  */
30 {
31  std::vector<unit_ptr >::iterator it = std::find_if(recall_list_.begin(), recall_list_.end(),
32  [&unit_id](const unit_ptr & ptr) { return ptr->id() == unit_id; });
33  if (it != recall_list_.end()) {
34  return *it;
35  } else {
36  return unit_ptr();
37  }
38 }
39 
40 /**
41  * Used to find units in vectors by their ID.
42  */
44 {
45  std::vector<unit_ptr >::const_iterator it = std::find_if(recall_list_.begin(), recall_list_.end(),
46  [&unit_id](const unit_ptr & ptr) { return ptr->id() == unit_id; });
47  if (it != recall_list_.end()) {
48  return *it;
49  } else {
50  return unit_ptr();
51  }
52 }
53 
54 /**
55  * Used to erase units from vectors by their ID.
56  */
57 void recall_list_manager::erase_if_matches_id(const std::string &unit_id)
58 {
59  // using unit_id as reference has potential to cause a crash if the underlying unit becomes invald
60  // https://github.com/wesnoth/wesnoth/issues/6603
61  recall_list_.erase(std::remove_if(recall_list_.begin(), recall_list_.end(),
62  [unit_id](const unit_ptr & ptr) { return ptr->id() == unit_id; }),
63  recall_list_.end());
64 }
65 
66 void recall_list_manager::add(const unit_ptr & ptr, int pos)
67 {
68  if (pos < 0 || pos >= static_cast<int>(recall_list_.size())) {
69  recall_list_.push_back(ptr);
70  }
71  else {
72  recall_list_.insert(recall_list_.begin() + pos, ptr);
73  }
74 }
75 
76 std::size_t recall_list_manager::find_index(const std::string & unit_id) const
77 {
78  std::vector<unit_ptr >::const_iterator it = std::find_if(recall_list_.begin(), recall_list_.end(),
79  [&unit_id](const unit_ptr & ptr) { return ptr->id() == unit_id; });
80 
81  return std::distance(recall_list_.begin(), it);
82 }
83 
84 unit_ptr recall_list_manager::extract_if_matches_id(const std::string &unit_id, int * pos)
85 {
86  std::vector<unit_ptr >::iterator it = std::find_if(recall_list_.begin(), recall_list_.end(),
87  [&unit_id](const unit_ptr & ptr) { return ptr->id() == unit_id; });
88  if (it != recall_list_.end()) {
89  unit_ptr ret = *it;
90  if(pos) {
91  *pos = it - recall_list_.begin();
92  }
93  recall_list_.erase(it);
94  return ret;
95  } else {
96  return unit_ptr();
97  }
98 }
99 
101 {
102  std::vector<unit_ptr >::iterator it = std::find_if(recall_list_.begin(), recall_list_.end(),
103  [uid](const unit_ptr & ptr) { return ptr->underlying_id() == uid; });
104  if (it != recall_list_.end()) {
105  return *it;
106  } else {
107  return unit_ptr();
108  }
109 }
110 
112 {
113  std::vector<unit_ptr >::const_iterator it = std::find_if(recall_list_.begin(), recall_list_.end(),
114  [uid](const unit_ptr & ptr) { return ptr->underlying_id() == uid; });
115  if (it != recall_list_.end()) {
116  return *it;
117  } else {
118  return unit_ptr();
119  }
120 }
121 
123 {
124  recall_list_.erase(std::remove_if(recall_list_.begin(), recall_list_.end(),
125  [uid](const unit_ptr & ptr) { return ptr->underlying_id() == uid; }),
126  recall_list_.end());
127 }
128 
130 {
131  std::vector<unit_ptr >::iterator it = std::find_if(recall_list_.begin(), recall_list_.end(),
132  [uid](const unit_ptr & ptr) { return ptr->underlying_id() == uid; });
133  if (it != recall_list_.end()) {
134  unit_ptr ret = *it;
135  recall_list_.erase(it);
136  return ret;
137  } else {
138  return unit_ptr();
139  }
140 }
141 
143  assert(idx < recall_list_.size());
144  return recall_list_.erase(recall_list_.begin()+idx);
145 }
146 
148  return recall_list_.erase(it);
149 }
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:26
unit_ptr extract_if_matches_underlying_id(std::size_t uid)
Find a unit by underlying id, and extract if found.
std::shared_ptr< const unit > unit_const_ptr
Definition: ptr.hpp:27
unit_ptr find_if_matches_id(const std::string &unit_id)
Find a unit by id.
iterator erase_index(std::size_t index)
Erase by index.
unit_ptr find_if_matches_underlying_id(std::size_t uid)
Find a unit by underlying id.
void erase_if_matches_id(const std::string &unit_id)
Erase any unit with this id.
unit_ptr extract_if_matches_id(const std::string &unit_id, int *pos=nullptr)
Find a unit by id, and extract from this object if found.
iterator erase(iterator it)
Erase an iterator to this object.
void erase_by_underlying_id(std::size_t uid)
Erase any unit with this underlying id.
void add(const unit_ptr &ptr, int pos=-1)
Add a unit to the list.
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
std::vector< unit_ptr > recall_list_
The underlying data struture.
std::size_t find_index(const std::string &unit_id) const
Find the index of a unit by its id.