[dali_2.1.30] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / helpers / round-robin-container-view.h
1
2 #ifndef DALI_TOOLKIT_INTERNAL_ROUND_ROBIN_CONTAINER_VIEW_H
3 #define DALI_TOOLKIT_INTERNAL_ROUND_ROBIN_CONTAINER_VIEW_H
4
5 /*
6  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 // EXTERNAL INCLUDES
23 #include <cstddef>
24 #include <vector>
25
26 namespace Dali
27 {
28 namespace Toolkit
29 {
30 namespace Internal
31 {
32 /**
33  * @brief RoundRobinContainerView is a view to a container that allows iterating through the elements cyclically.
34  */
35 template<typename T>
36 class RoundRobinContainerView
37 {
38 public:
39   using ContainerType = std::vector<T>;
40
41   /**
42    * @brief Constructs a new RoundRobinControlView with the given number elements using the provided factory.
43    * @param[in] numberOfElements The number of elements in the container
44    * @param[in] factory          Factory function of functor that will be used to create instances of the elements
45    */
46   template<typename FactoryType>
47   RoundRobinContainerView(size_t numberOfElements, const FactoryType& factory)
48   : mElements(),
49     mNextIndex{}
50   {
51     mElements.reserve(numberOfElements);
52     for(unsigned i = {}; i < numberOfElements; ++i)
53     {
54       mElements.push_back(factory());
55     }
56   }
57
58   /**
59    * @brief Clear all elements.
60    */
61   void Clear()
62   {
63     mElements.clear();
64   }
65
66   /**
67    * @brief Reset the position of the iterator returned by GetNext() to the first element.
68    */
69   void Reset()
70   {
71     mNextIndex = 0u;
72   }
73
74   /**
75    * @brief Returns the next element on the container.
76    * @return Iterator for the next element
77    */
78   typename ContainerType::iterator GetNext()
79   {
80     SetValidNextIndex();
81
82     return mElements.begin() + mNextIndex++;
83   }
84
85   /**
86    * @brief Returns the iterator to the end of the container.
87    *
88    * Can be used to compare against GetNext() to check if the container is empty.
89    *
90    * @return The container end() element
91    */
92   typename ContainerType::const_iterator End() const
93   {
94     return mElements.cend();
95   }
96
97   /**
98    * @brief Returns the element count.
99    * @return The element count
100    */
101   size_t GetElementCount() const
102   {
103     return mElements.size();
104   }
105
106   // default members
107   ~RoundRobinContainerView() = default;
108
109   RoundRobinContainerView(const RoundRobinContainerView&) = delete;
110   RoundRobinContainerView& operator=(const RoundRobinContainerView&) = delete;
111   RoundRobinContainerView(RoundRobinContainerView&&)                 = default;
112   RoundRobinContainerView& operator=(RoundRobinContainerView&&) = default;
113
114 private:
115   /**
116    * @brief Check the current index and reset if necessary.
117    */
118   void SetValidNextIndex()
119   {
120     if(mNextIndex >= mElements.size())
121     {
122       Reset();
123     }
124   }
125
126 private:
127   ContainerType mElements;  //< container of elements
128   size_t        mNextIndex; //< index to the next element to be viewed
129 };
130
131 } // namespace Internal
132
133 } // namespace Toolkit
134
135 } // namespace Dali
136
137 #endif // DALI_TOOLKIT_INTERNAL_ROUND_ROBIN_CONTAINER_VIEW_H