Compare commits
2
Commits
85f5de1be2
...
c62c9dc3de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c62c9dc3de | ||
|
|
78cb890ed7 |
No files matched your search
@@ -0,0 +1,3 @@
|
|||||||
|
5-8
|
||||||
|
0-2
|
||||||
|
4-7
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
swap position 4 with position 0
|
||||||
|
swap letter d with letter b
|
||||||
|
reverse positions 0 through 4
|
||||||
|
rotate left 1
|
||||||
|
move position 1 to position 4
|
||||||
|
move position 3 to position 0
|
||||||
|
rotate based on position of letter b
|
||||||
|
rotate based on position of letter d
|
||||||
+37
-7
@@ -2,30 +2,60 @@
|
|||||||
|
|
||||||
namespace y2016::day20
|
namespace y2016::day20
|
||||||
{
|
{
|
||||||
REGISTER_DAY(2016, Day20, std::vector<int>, int);
|
using Input = std::vector<std::pair<uint64_t, uint64_t>>;
|
||||||
|
REGISTER_DAY(2016, Day20, Input, uint32_t);
|
||||||
|
|
||||||
REGISTER_TEST_EXAMPLE(2016, Day20, ExampleInput, 1, 0);
|
REGISTER_TEST_EXAMPLE(2016, Day20, ExampleInput, 1, 3);
|
||||||
REGISTER_TEST(2016, Day20, Input, 1, 0);
|
REGISTER_TEST(2016, Day20, Input, 1, 19449262);
|
||||||
REGISTER_TEST_EXAMPLE(2016, Day20, ExampleInput, 2, 0);
|
REGISTER_TEST_EXAMPLE(2016, Day20, ExampleInput, 2, 2);
|
||||||
REGISTER_TEST(2016, Day20, Input, 2, 0);
|
REGISTER_TEST(2016, Day20, Input, 2, 119);
|
||||||
|
|
||||||
READ_INPUT(input)
|
READ_INPUT(input)
|
||||||
{
|
{
|
||||||
std::vector<int> vec;
|
std::vector<std::pair<uint64_t, uint64_t>> vec;
|
||||||
std::string str;
|
std::string str;
|
||||||
while (getline(input, str))
|
while (getline(input, str))
|
||||||
{
|
{
|
||||||
|
std::pair<uint32_t, uint32_t> pair;
|
||||||
|
std::stringstream ss{str};
|
||||||
|
ss >> pair.first >> "-" >> pair.second;
|
||||||
|
vec.emplace_back(pair);
|
||||||
}
|
}
|
||||||
|
std::sort(vec.begin(), vec.end());
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT1(input)
|
OUTPUT1(input)
|
||||||
{
|
{
|
||||||
|
if (input.front().first != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < input.size(); i++)
|
||||||
|
{
|
||||||
|
if (input[i].second + 1 < input[i + 1].first)
|
||||||
|
return input[i].second + 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT2(input)
|
OUTPUT2(input)
|
||||||
{
|
{
|
||||||
return 0;
|
uint64_t allowed = input.front().first;
|
||||||
|
uint64_t currentMax = input.front().second;
|
||||||
|
for (int i = 1; i < input.size(); i++)
|
||||||
|
{
|
||||||
|
if (currentMax < input[i].first - 1)
|
||||||
|
{
|
||||||
|
allowed += input[i].first - currentMax - 1;
|
||||||
|
currentMax = input[i].second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentMax = std::max(currentMax, input[i].second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t max = isExample ? 9 : std::numeric_limits<uint32_t>::max();
|
||||||
|
allowed += max - currentMax;
|
||||||
|
return allowed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+206
-8
@@ -2,30 +2,228 @@
|
|||||||
|
|
||||||
namespace y2016::day21
|
namespace y2016::day21
|
||||||
{
|
{
|
||||||
REGISTER_DAY(2016, Day21, std::vector<int>, int);
|
enum class Operator
|
||||||
|
{
|
||||||
|
Swap,
|
||||||
|
SwapLetter,
|
||||||
|
Rotate,
|
||||||
|
RotatePos,
|
||||||
|
Reverse,
|
||||||
|
Move
|
||||||
|
};
|
||||||
|
|
||||||
REGISTER_TEST_EXAMPLE(2016, Day21, ExampleInput, 1, 0);
|
struct Instruction
|
||||||
REGISTER_TEST(2016, Day21, Input, 1, 0);
|
{
|
||||||
REGISTER_TEST_EXAMPLE(2016, Day21, ExampleInput, 2, 0);
|
Operator op;
|
||||||
REGISTER_TEST(2016, Day21, Input, 2, 0);
|
int arg1;
|
||||||
|
int arg2;
|
||||||
|
};
|
||||||
|
|
||||||
|
REGISTER_DAY(2016, Day21, std::vector<Instruction>, std::string);
|
||||||
|
|
||||||
|
REGISTER_TEST_EXAMPLE(2016, Day21, ExampleInput, 1, "decab");
|
||||||
|
REGISTER_TEST(2016, Day21, Input, 1, "hcdefbag");
|
||||||
|
REGISTER_TEST(2016, Day21, Input, 2, "fbhaegdc");
|
||||||
|
|
||||||
READ_INPUT(input)
|
READ_INPUT(input)
|
||||||
{
|
{
|
||||||
std::vector<int> vec;
|
std::vector<Instruction> vec;
|
||||||
std::string str;
|
std::string str;
|
||||||
while (getline(input, str))
|
while (getline(input, str))
|
||||||
{
|
{
|
||||||
|
Instruction instruction;
|
||||||
|
std::stringstream ss{str};
|
||||||
|
if (Helper::StartsWith(str, "swap position"))
|
||||||
|
{
|
||||||
|
instruction.op = Operator::Swap;
|
||||||
|
ss >> "swap position " >> instruction.arg1 >> "with position " >> instruction.arg2;
|
||||||
|
}
|
||||||
|
else if (Helper::StartsWith(str, "swap letter"))
|
||||||
|
{
|
||||||
|
instruction.op = Operator::SwapLetter;
|
||||||
|
char c1, c2;
|
||||||
|
ss >> "swap letter " >> c1 >> "with letter " >> c2;
|
||||||
|
instruction.arg1 = c1;
|
||||||
|
instruction.arg2 = c2;
|
||||||
|
}
|
||||||
|
else if (Helper::StartsWith(str, "rotate left"))
|
||||||
|
{
|
||||||
|
instruction.op = Operator::Rotate;
|
||||||
|
ss >> "rotate left" >> instruction.arg1;
|
||||||
|
instruction.arg1 = -instruction.arg1;
|
||||||
|
}
|
||||||
|
else if (Helper::StartsWith(str, "rotate right"))
|
||||||
|
{
|
||||||
|
instruction.op = Operator::Rotate;
|
||||||
|
ss >> "rotate right" >> instruction.arg1;
|
||||||
|
}
|
||||||
|
else if (Helper::StartsWith(str, "rotate based"))
|
||||||
|
{
|
||||||
|
instruction.op = Operator::RotatePos;
|
||||||
|
char c;
|
||||||
|
ss >> "rotate based on position of letter " >> c;
|
||||||
|
instruction.arg1 = c;
|
||||||
|
}
|
||||||
|
else if (str[0] == 'r')
|
||||||
|
{
|
||||||
|
instruction.op = Operator::Reverse;
|
||||||
|
ss >> "reverse positions " >> instruction.arg1 >> "through " >> instruction.arg2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
instruction.op = Operator::Move;
|
||||||
|
ss >> "move position " >> instruction.arg1 >> "to position " >> instruction.arg2;
|
||||||
|
}
|
||||||
|
vec.emplace_back(instruction);
|
||||||
}
|
}
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT1(input)
|
OUTPUT1(input)
|
||||||
{
|
{
|
||||||
return 0;
|
CyclicVector<char> data{isExample ? "abcde" : "abcdefgh"};
|
||||||
|
for (const auto& instruction : input)
|
||||||
|
{
|
||||||
|
switch (instruction.op)
|
||||||
|
{
|
||||||
|
case Operator::Swap:
|
||||||
|
{
|
||||||
|
std::swap(data[instruction.arg1], data[instruction.arg2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::SwapLetter:
|
||||||
|
{
|
||||||
|
size_t i1 = data.Find(instruction.arg1);
|
||||||
|
size_t i2 = data.Find(instruction.arg2);
|
||||||
|
std::swap(data[i1], data[i2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::Rotate:
|
||||||
|
{
|
||||||
|
data.Rotate(instruction.arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::RotatePos:
|
||||||
|
{
|
||||||
|
size_t pos = data.Find(instruction.arg1);
|
||||||
|
int additional = pos >= 4 ? 1 : 0;
|
||||||
|
data.Rotate(pos + 1 + additional);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::Reverse:
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < (instruction.arg2 - instruction.arg1 + 1) / 2; i++)
|
||||||
|
{
|
||||||
|
std::swap(data[instruction.arg1 + i], data[instruction.arg2 - i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::Move:
|
||||||
|
{
|
||||||
|
if (instruction.arg1 < instruction.arg2)
|
||||||
|
{
|
||||||
|
char c = data[instruction.arg1];
|
||||||
|
for (size_t i = instruction.arg1; i < instruction.arg2; i++)
|
||||||
|
{
|
||||||
|
data[i] = data[i + 1];
|
||||||
|
}
|
||||||
|
data[instruction.arg2] = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char c = data[instruction.arg1];
|
||||||
|
for (size_t i = instruction.arg1; i > instruction.arg2; i--)
|
||||||
|
{
|
||||||
|
data[i] = data[i - 1];
|
||||||
|
}
|
||||||
|
data[instruction.arg2] = c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string str;
|
||||||
|
for (size_t i = 0; i < data.size(); i++)
|
||||||
|
{
|
||||||
|
str.push_back(data[i]);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT2(input)
|
OUTPUT2(input)
|
||||||
{
|
{
|
||||||
return 0;
|
CyclicVector<char> data{"fbgdceah"};
|
||||||
|
std::map<int, int> rotatePosMap;
|
||||||
|
for (int i = 0; i < data.size(); i++)
|
||||||
|
{
|
||||||
|
int result = (i + i + 1 + (i >= 4 ? 1 : 0)) % data.size();
|
||||||
|
rotatePosMap.emplace(result, i - result);
|
||||||
|
}
|
||||||
|
for (int i = input.size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
const auto& instruction = input[i];
|
||||||
|
switch (instruction.op)
|
||||||
|
{
|
||||||
|
case Operator::Swap:
|
||||||
|
{
|
||||||
|
std::swap(data[instruction.arg1], data[instruction.arg2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::SwapLetter:
|
||||||
|
{
|
||||||
|
size_t i1 = data.Find(instruction.arg1);
|
||||||
|
size_t i2 = data.Find(instruction.arg2);
|
||||||
|
std::swap(data[i1], data[i2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::Rotate:
|
||||||
|
{
|
||||||
|
data.Rotate(-instruction.arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::RotatePos:
|
||||||
|
{
|
||||||
|
size_t pos = data.Find(instruction.arg1);
|
||||||
|
data.Rotate(rotatePosMap[pos]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::Reverse:
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < (instruction.arg2 - instruction.arg1 + 1) / 2; i++)
|
||||||
|
{
|
||||||
|
std::swap(data[instruction.arg1 + i], data[instruction.arg2 - i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Operator::Move:
|
||||||
|
{
|
||||||
|
if (instruction.arg2 < instruction.arg1)
|
||||||
|
{
|
||||||
|
char c = data[instruction.arg2];
|
||||||
|
for (size_t i = instruction.arg2; i < instruction.arg1; i++)
|
||||||
|
{
|
||||||
|
data[i] = data[i + 1];
|
||||||
|
}
|
||||||
|
data[instruction.arg1] = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char c = data[instruction.arg2];
|
||||||
|
for (size_t i = instruction.arg2; i > instruction.arg1; i--)
|
||||||
|
{
|
||||||
|
data[i] = data[i - 1];
|
||||||
|
}
|
||||||
|
data[instruction.arg1] = c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string str;
|
||||||
|
for (auto c : data)
|
||||||
|
{
|
||||||
|
str.push_back(c);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "common/lib/Array2D.h"
|
#include "common/lib/Array2D.h"
|
||||||
#include "common/lib/Array3D.h"
|
#include "common/lib/Array3D.h"
|
||||||
#include "common/lib/Array4D.h"
|
#include "common/lib/Array4D.h"
|
||||||
|
#include "common/lib/CyclicVector.h"
|
||||||
#include "common/lib/Graph.h"
|
#include "common/lib/Graph.h"
|
||||||
#include "common/lib/Helper.h"
|
#include "common/lib/Helper.h"
|
||||||
#include "common/lib/Input.h"
|
#include "common/lib/Input.h"
|
||||||
|
|||||||
@@ -0,0 +1,354 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct CyclicVector
|
||||||
|
{
|
||||||
|
std::vector<T> vector;
|
||||||
|
size_t offset{0};
|
||||||
|
|
||||||
|
CyclicVector(const std::initializer_list<T>& vector)
|
||||||
|
: vector{vector}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CyclicVector(const std::vector<T>& vector)
|
||||||
|
: vector{vector}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U = T, typename = std::enable_if_t<std::is_same_v<U, char>>>
|
||||||
|
CyclicVector(const std::string& str)
|
||||||
|
: vector{str.begin(), str.end()}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t N, typename U = T, typename = std::enable_if_t<std::is_same_v<U, char>>>
|
||||||
|
CyclicVector(const char (&str)[N])
|
||||||
|
{
|
||||||
|
vector.resize(N - 1); // don't include \0 character
|
||||||
|
for (size_t i = 0; i < N - 1; i++)
|
||||||
|
{
|
||||||
|
vector[i] = str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rotate(int i)
|
||||||
|
{
|
||||||
|
if (i < 0)
|
||||||
|
RotateLeft(-i);
|
||||||
|
else
|
||||||
|
RotateRight(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotateRight(int i)
|
||||||
|
{
|
||||||
|
offset = (offset + vector.size() - (i % vector.size())) % vector.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotateLeft(size_t i)
|
||||||
|
{
|
||||||
|
offset = (offset + i) % vector.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator[](size_t i)
|
||||||
|
{
|
||||||
|
return vector[(i + offset) % vector.size()];
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator[](size_t i) const
|
||||||
|
{
|
||||||
|
return vector[(i + offset) % vector.size()];
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return vector.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return vector.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Find(const T& t) const
|
||||||
|
{
|
||||||
|
return std::find(begin(), end(), t).GetPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct iterator;
|
||||||
|
struct const_iterator;
|
||||||
|
|
||||||
|
iterator begin()
|
||||||
|
{
|
||||||
|
return iterator{*this, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end()
|
||||||
|
{
|
||||||
|
return iterator{*this, vector.size()};
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const
|
||||||
|
{
|
||||||
|
return const_iterator{*this, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator end() const
|
||||||
|
{
|
||||||
|
return const_iterator{*this, vector.size()};
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator cbegin() const
|
||||||
|
{
|
||||||
|
return const_iterator{*this, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator cend() const
|
||||||
|
{
|
||||||
|
return const_iterator{*this, vector.size()};
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const CyclicVector& vector)
|
||||||
|
{
|
||||||
|
os << "[";
|
||||||
|
if (!vector.empty())
|
||||||
|
os << vector[0];
|
||||||
|
|
||||||
|
for (auto it = vector.cbegin() + 1; it != vector.cend(); it++)
|
||||||
|
{
|
||||||
|
os << ", " << *it;
|
||||||
|
}
|
||||||
|
os << "]";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
class iterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CyclicVector<T>& data;
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
using value_type = T;
|
||||||
|
using difference_type = int;
|
||||||
|
using pointer = T*;
|
||||||
|
using reference = T&;
|
||||||
|
|
||||||
|
iterator(CyclicVector<T>& data, size_t pos)
|
||||||
|
: data{data},
|
||||||
|
pos{pos}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetPos() const
|
||||||
|
{
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
reference operator*() const
|
||||||
|
{
|
||||||
|
return data[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer operator->() const
|
||||||
|
{
|
||||||
|
return &data[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator& operator++()
|
||||||
|
{
|
||||||
|
++pos;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator operator++(int)
|
||||||
|
{
|
||||||
|
iterator ret = *this;
|
||||||
|
++(*this);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator& operator--()
|
||||||
|
{
|
||||||
|
--pos;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator operator--(int)
|
||||||
|
{
|
||||||
|
iterator ret = *this;
|
||||||
|
--(*this);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator& operator+=(size_t advance)
|
||||||
|
{
|
||||||
|
if (std::numeric_limits<size_t>::max() - pos < advance)
|
||||||
|
{
|
||||||
|
pos = data.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos += advance;
|
||||||
|
if (pos >= data.size())
|
||||||
|
pos = data.size();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator& operator-=(size_t advance)
|
||||||
|
{
|
||||||
|
if (advance > pos)
|
||||||
|
{
|
||||||
|
pos = data.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos -= advance;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator operator+(size_t advance) const
|
||||||
|
{
|
||||||
|
iterator ret = *this;
|
||||||
|
ret += advance;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator operator-(size_t advance) const
|
||||||
|
{
|
||||||
|
iterator ret = *this;
|
||||||
|
ret -= advance;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const iterator& other) const
|
||||||
|
{
|
||||||
|
return pos == other.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const iterator& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class const_iterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const CyclicVector<T>& data;
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
using value_type = T;
|
||||||
|
using difference_type = int;
|
||||||
|
using pointer = const T*;
|
||||||
|
using reference = const T&;
|
||||||
|
|
||||||
|
const_iterator(const CyclicVector<T>& data, size_t pos)
|
||||||
|
: data{data},
|
||||||
|
pos{pos}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetPos() const
|
||||||
|
{
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
reference operator*() const
|
||||||
|
{
|
||||||
|
return data[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer operator->() const
|
||||||
|
{
|
||||||
|
return &data[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator& operator++()
|
||||||
|
{
|
||||||
|
++pos;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator operator++(int)
|
||||||
|
{
|
||||||
|
const_iterator ret = *this;
|
||||||
|
++(*this);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator& operator--()
|
||||||
|
{
|
||||||
|
--pos;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator operator--(int)
|
||||||
|
{
|
||||||
|
const_iterator ret = *this;
|
||||||
|
--(*this);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator& operator+=(size_t advance)
|
||||||
|
{
|
||||||
|
if (std::numeric_limits<size_t>::max() - pos < advance)
|
||||||
|
{
|
||||||
|
pos = data.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos += advance;
|
||||||
|
if (pos >= data.size())
|
||||||
|
pos = data.size();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator& operator-=(size_t advance)
|
||||||
|
{
|
||||||
|
if (advance > pos)
|
||||||
|
{
|
||||||
|
pos = data.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos -= advance;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator operator+(size_t advance) const
|
||||||
|
{
|
||||||
|
const_iterator ret = *this;
|
||||||
|
ret += advance;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator operator-(size_t advance) const
|
||||||
|
{
|
||||||
|
const_iterator ret = *this;
|
||||||
|
ret -= advance;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const const_iterator& other) const
|
||||||
|
{
|
||||||
|
return pos == other.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const const_iterator& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
Reference in new issue
Block a user