Last active
July 2, 2019 14:00
-
-
Save rioki/5da93d5b398d8b1e2adbf525129e9655 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2019 Sean Farrell <[email protected]> | |
// This work is free. You can redistribute it and/or modify it under the | |
// terms of the Do What The Fuck You Want To Public License, Version 2, | |
// as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. | |
#ifndef _ROUND_ROBIN_H_ | |
#define _ROUND_ROBIN_H_ | |
#include <array> | |
/*! | |
* A container of fixed size that cycles a given amount of items. | |
*/ | |
template <typename Type, size_t COUNT> | |
class round_robin | |
{ | |
public: | |
/*! | |
* Returns the number of elements | |
* | |
* @returns The number of elements in the container. | |
*/ | |
size_t size() const | |
{ | |
return COUNT; | |
} | |
/*! | |
* Access specified element | |
* | |
* Returns a reference to the element at specified location pos. | |
* | |
* @param pos position of the element to return | |
* @returns reference to the requested element | |
* | |
* @{ | |
*/ | |
Type& operator [] (ptrdiff_t pos) | |
{ | |
auto i = static_cast<ptrdiff_t>(index) + (pos % static_cast<ptrdiff_t>(COUNT)); | |
if (i < 0) | |
{ | |
i += COUNT; | |
} | |
if (i >= COUNT) | |
{ | |
i -= COUNT; | |
} | |
return values[i]; | |
} | |
const Type& operator [] (ptrdiff_t pos) const | |
{ | |
return const_cast<round_robin*>(this)->operator[](pos); | |
} | |
/*! @} */ | |
/*! | |
* access specified element with bounds checking | |
* | |
* Returns a reference to the element at specified location pos, with bounds checking. | |
* If pos is not within the range of the container, an exception of type std::out_of_range is thrown. | |
* | |
* @param pos position of the element to return | |
* @returns reference to the requested element | |
* @throws std::out_of_range if `!(abs(pos) < size())` | |
* | |
* @{ | |
*/ | |
Type& at(ptrdiff_t pos) | |
{ | |
auto i = static_cast<ptrdiff_t>(index) + (pos % static_cast<ptrdiff_t>(COUNT)); | |
if (i < 0) | |
{ | |
i += COUNT; | |
} | |
if (i >= COUNT) | |
{ | |
i -= COUNT; | |
} | |
return values.at(i); | |
} | |
const Type& at(ptrdiff_t pos) const | |
{ | |
return const_cast<round_robin*>(this)->at(pos); | |
} | |
/*! @} */ | |
/*! | |
* Access a single item regardless of the current head value. | |
* @{ | |
*/ | |
Type& front() | |
{ | |
return values[index]; | |
} | |
const Type& front() const | |
{ | |
return values[index]; | |
} | |
/*! @} */ | |
/*! | |
* Rotate the sequence one revolution | |
*/ | |
void rotate() | |
{ | |
index = (index + 1u) % COUNT; | |
} | |
private: | |
size_t index = 0; | |
std::array<Type, COUNT> values; | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment