23 namespace image {
class locator; }
25 template<
typename T,
typename D>
29 using data_t = std::vector<std::pair<D, int>>;
40 return data_.size() <= 1;
46 for(
const auto& entry :
data_) {
47 total += entry.second;
86 const std::vector<std::string> comma_split =
utils::split(input,
',', split_flag);
87 const int time_chunk = std::max<int>(1,
duration / std::max<int>(comma_split.size(), 1));
89 for(
const auto& entry : comma_split) {
90 std::vector<std::string> colon_split =
utils::split(entry,
':', split_flag);
94 time = (colon_split.size() > 1) ? std::stoi(colon_split[1]) : time_chunk;
95 }
catch(
const std::invalid_argument&) {
100 std::vector<std::string> range =
utils::split(colon_split[0],
'~',split_flag);
101 T range0 = lexical_cast<T>(range[0]);
102 T range1 = (range.size() > 1) ? lexical_cast<T>(range[1]) : range0;
104 base_data.push_back({{range0, range1}, time});
114 if(base_data.empty()) {
120 const int searched_time = std::clamp(current_time, 0, base_duration);
122 while(time < searched_time &&
i < base_data.size()) {
123 time += base_data[
i].second;
129 time -= base_data[
i].second;
132 const T first = base_data[
i].first.first;
133 const T second = base_data[
i].first.second;
136 static_cast<double>(searched_time - time) /
137 static_cast<double>(base_data[
i].second)
138 ) * (second - first) + first);
144 return base_data.empty() || (base_data.size() == 1 && base_data[0].first.first == base_data[0].first.second);
161 int time_chunk = std::max<int>(
duration, 1);
163 if(
duration > 1 && !first_pass.empty()) {
165 int total_specified_time = 0;
167 for(
const std::string& fp_string : first_pass) {
168 std::vector<std::string> second_pass =
utils::split(fp_string,
':');
169 if(second_pass.size() > 1) {
171 total_specified_time += std::stoi(second_pass[1]);
172 }
catch(
const std::invalid_argument&) {
178 time_chunk = std::max<int>((
duration - total_specified_time) / first_pass.size(), 1);
181 for(
const std::string& fp_string : first_pass) {
182 std::vector<std::string> second_pass =
utils::split(fp_string,
':');
183 if(second_pass.size() > 1) {
185 base_data.push_back({std::move(second_pass[0]), std::stoi(second_pass[1])});
186 }
catch(
const std::invalid_argument&) {
190 base_data.push_back({std::move(second_pass[0]) ,time_chunk});
199 if(base_data.empty()) {
206 while(time < current_time &&
i < base_data.size()) {
207 time += base_data[
i].second;
216 return base_data[
i].first;
const data_t & data() const
virtual ~progressive_base()
std::vector< std::pair< D, int > > data_t
progressive_base(const std::string &input)
std::string get_original() const
virtual const T get_current_element(int current_time, T default_val) const =0
virtual bool does_not_change() const
virtual const T get_current_element(int current_time, T default_val=T()) const override
progressive_pair(const std::string &input="", int duration=0)
bool does_not_change() const override
virtual const T get_current_element(int current_time, T default_val=T()) const override
progressive_single(const std::string &input="", int duration=0)
New lexcical_cast header.
Functions to load and save images from/to disk.
std::vector< std::string > square_parenthetical_split(const std::string &val, const char separator, const std::string &left, const std::string &right, const int flags)
Similar to parenthetical_split, but also expands embedded square brackets.
std::vector< std::string > split(const config_attribute_value &val)
Thrown when a lexical_cast fails.