blob: 25c9751206f16eb8de40943a30edb7d49b20c8e5 [file] [log] [blame]
// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
//
// This file is part of GNU uCommon C++.
//
// GNU uCommon C++ is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU uCommon C++ is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
/**
* Support for various automatic counting objects.
* This header defines templates for various kinds of automatic counting
* and sequencing objects. Templates are used to allow manipulation of
* various numerical-like types.
* @file ucommon/counter.h
*/
#ifndef _UCOMMON_COUNTER_H_
#define _UCOMMON_COUNTER_H_
#ifndef _UCOMMON_CONFIG_H_
#include <ucommon/platform.h>
#endif
NAMESPACE_UCOMMON
/**
* Automatic integer counting class. This is an automatic counting object
* that is used to retrieve a new integer value between 0 and n each time
* the object is referenced. When reaching the last n value, the object
* restarts at 0, and so is used to retrieve a sequence of values in order.
* @author David Sugar <dyfet@gnutelephony.org>
*/
class __EXPORT counter
{
private:
unsigned value, cycle;
public:
/**
* Initialize integer counter of unknown size.
*/
counter();
/**
* Initialize integer counter for a range of values.
* @param limit before recycling to zero.
*/
counter(unsigned limit);
/**
* Get the next counter value.
* @return next counter value.
*/
unsigned get(void);
/**
* Get the range of values before recycling.
* @return counter limit.
*/
inline unsigned range(void)
{return cycle;};
/**
* Reference next counter value through pointer operation.
* @return next counter value.
*/
inline unsigned operator*()
{return get();};
/**
* Reference next counter value by casting to integer.
* @return next counter value.
*/
inline operator unsigned()
{return get();};
/**
* Assign the value of the counter.
* @param value to assign.
*/
void operator=(unsigned value);
};
/**
* Automatically return a sequence of untyped objects. This is an automatic
* counter based class which returns the next pointer in an array of pointers
* and restarts the list when reaching the end. This is used to support the
* sequence template.
* @author David Sugar <dyfet@gnutelephony.org>
*/
class __EXPORT SeqCounter : protected counter
{
private:
void *item;
size_t offset;
protected:
SeqCounter(void *start, size_t size, unsigned count);
void *get(void);
void *get(unsigned idx);
public:
/**
* Used to directly assign sequence position in template.
* @param inc_offset in sequence to reset sequencing to.
*/
inline void operator=(unsigned inc_offset)
{counter::operator=(inc_offset);};
};
/**
* Automatically toggle a bool on each reference.
* @author David Sugar <dyfet@gnutelephony.org>
*/
class __EXPORT toggle
{
private:
bool value;
public:
inline toggle()
{value = false;};
bool get(void);
inline bool operator*()
{return get();};
inline void operator=(bool v)
{value = v;};
inline operator bool()
{return get();};
};
/**
* A template to return a sequence of objects of a specified type.
* This is used to return a different member in a sequence of objects of
* a specified type during each reference to the sequencer.
* @author David Sugar <dyfet@gnutelephony.org>
*/
template <class T>
class sequence : public SeqCounter
{
protected:
inline T *get(unsigned idx)
{return static_cast<T *>(SeqCounter::get(idx));};
public:
/**
* Create a template auto-sequence from a list of typed pointers.
* @param array of typed values to sequence on reference.
* @param size of list of typed values.
*/
inline sequence(T *array, unsigned size) :
SeqCounter(array, sizeof(T), size) {};
/**
* Return next typed member of the sequence.
* @return next typed member of sequence.
*/
inline T* get(void)
{return static_cast<T *>(SeqCounter::get());};
/**
* Return next typed member of the sequence by pointer reference.
* @return next typed member of sequence.
*/
inline T& operator*()
{return *get();};
/**
* Return next typed member of the sequence by casted reference.
* @return next typed member of sequence.
*/
inline operator T&()
{return *get();};
/**
* Return a specific typed member from the sequence list.
* @param offset of member to return.
* @return typed value at the specified offset.
*/
inline T& operator[](unsigned offset)
{return *get(offset);};
};
/**
* A convenience typecast for integer counters.
*/
typedef counter counter_t;
/**
* A convenience typecast for auto-toggled bools.
*/
typedef toggle toggle_t;
END_NAMESPACE
#endif