1// Aseprite Document Library
2// Copyright (C) 2019 Igara Studio S.A.
3//
4// This file is released under the terms of the MIT license.
5// Read LICENSE.txt for more information.
6
7#ifndef DOC_SELECTED_OBJECTS_H_INCLUDED
8#define DOC_SELECTED_OBJECTS_H_INCLUDED
9#pragma once
10
11#include "base/debug.h"
12#include "doc/object.h"
13#include "doc/object_id.h"
14
15#include <set>
16
17namespace doc {
18
19 // A set of selected objects (e.g. select set of slices)
20 class SelectedObjects {
21 public:
22 typedef std::set<ObjectId> Set;
23 typedef Set::iterator iterator;
24 typedef Set::const_iterator const_iterator;
25
26 template<typename T>
27 class IteratableAs {
28 public:
29 class IteratorAs {
30 public:
31 typedef T* value_type;
32 typedef std::ptrdiff_t difference_type;
33 typedef T** pointer;
34 typedef T*& reference;
35 typedef std::forward_iterator_tag iterator_category;
36 IteratorAs(const const_iterator& it) : m_it(it) { }
37 bool operator==(const IteratorAs& other) const {
38 return m_it == other.m_it;
39 }
40 bool operator!=(const IteratorAs& other) const {
41 return !operator==(other);
42 }
43 T* operator*() const {
44 return doc::get<T>(*m_it);
45 }
46 IteratorAs& operator++() {
47 ++m_it;
48 return *this;
49 }
50 private:
51 const_iterator m_it;
52 };
53
54 typedef IteratorAs iterator;
55
56 iterator begin() const { return m_begin; }
57 iterator end() const { return m_end; }
58
59 IteratableAs(const SelectedObjects& objs)
60 : m_begin(objs.begin())
61 , m_end(objs.end()) { }
62 private:
63 IteratorAs m_begin, m_end;
64 };
65
66 iterator begin() { return m_set.begin(); }
67 iterator end() { return m_set.end(); }
68 const_iterator begin() const { return m_set.begin(); }
69 const_iterator end() const { return m_set.end(); }
70
71 bool empty() const { return m_set.empty(); }
72 size_t size() const { return m_set.size(); }
73
74 void clear() {
75 m_set.clear();
76 }
77
78 void insert(const ObjectId id) {
79 m_set.insert(id);
80 }
81
82 bool contains(const ObjectId id) const {
83 return (m_set.find(id) != end());
84 }
85
86 void erase(const ObjectId id) {
87 auto it = m_set.find(id);
88 if (it != end())
89 m_set.erase(it);
90 }
91
92 template<typename T>
93 T* frontAs() const {
94 ASSERT(!m_set.empty());
95 return doc::get<T>(*m_set.begin());
96 }
97
98 template<typename T>
99 IteratableAs<T> iterateAs() const { return IteratableAs<T>(*this); }
100
101 private:
102 Set m_set;
103 };
104
105} // namespace doc
106
107#endif // DOC_SELECTED_OBJECTS_H_INCLUDED
108