Нет темплейтов в Embedded C++? А если так?
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено C++ 25 мая 2005 г. 15:15

Достал сабж. Посему взял и написал нижеследующее.
Отлично работает в IAR для AVR.

Файл list.h:


#ifndef LIST_H_INCLUDED
#define LIST_H_INCLUDED
/*
Темплейт для создания списка объектов, подобного std::list и std:queue из STL
Т.к. в Embedded C++ нет темплейтов, он сделан с помощью #define.
Копии объектов создаются в хипе. Объекты должны содержать copy constructor,
если это необходимо.

Пример объявления типа:
DECLARE_LIST(IntPtrList, int*); //Список указателей на int
DECLARE_LIST(MyObjList, MyObj); //Список объектов

Пример использования:
//В хедере: объявить класс IntPtrList как список объектов типа int
DECLARE_LIST(IntPtrList, int);
//В .cpp файле:
IntPtrList intlist;
intlist.push_back(1);
intlist.push_back(12);
intlist.push_back(23);
intlist.push_back(34);
IntPtrList::iterator it = intlist.begin() // Возвращает итератор, указывающий на первый объект в списке
while (it != intlist.end()) printf("%d", *it++); //Распечатать содержимое списка (1 12 23 34)
intlist.pop_front(); //Удалить первый элемент. Останутся 12 23 34
it = intlist.begin();
intlist.erase(++it); //Удалить ВТОРОЙ элемент списка. Останутся 12 и 34
и т.д.

Интерфейс:
bool push_back (const OBJ& in)
bool push_front (const OBJ& in)
void pop_front() // Deletes the element at the beginning of a list
void pop_back() // Deletes the element at the beginning of a list
iterator begin() // Возвращает итератор, указывающий на первый объект в списке
iterator end() // Возвращает пустой итератор (за концом списка)
OBJ& back() // Возвращает ссылку на последний элемент списка (если список пуст - результат не определен)
OBJ& front() // Возвращает ссылку на первый элемент списка (если список пуст - результат не определен)
void erase(iterator _Where) //Удаляет элемент из списка
unsigned int size() //Возвращает количество элементов в списке
*/

#define DECLARE_LIST(_Classname_,_Classobj_) \
typedef _Classobj_ _Classname_##_Classobj__; \
class _Classname_ { \
struct PtrWrapper { \
_Classname_##_Classobj__* pobj; \
PtrWrapper* next; \
PtrWrapper* prev; \
PtrWrapper(const _Classname_##_Classobj__& in) {next=prev=0; pobj = new _Classname_##_Classobj__(in);} \
~PtrWrapper() { delete pobj; } \
}; \
PtrWrapper* _front; \
PtrWrapper* _back; \
unsigned int _size; \
public: \
struct iterator { \
const PtrWrapper* pit; \
iterator() {pit=0;} \
iterator(const PtrWrapper* in) {pit=in;} \
iterator(const iterator& in) {pit=in.pit;} \
iterator& operator = (const iterator& in) { pit=in.pit; return *this; } \
iterator& operator ++() { if (pit) pit=pit->next; return *this; } \
iterator operator ++(int) { iterator tmp(*this); if (pit) pit=pit->next; return tmp; } \
iterator& operator --() { if (pit) pit=pit->prev; return *this; } \
iterator operator --(int) { iterator tmp(*this); if (pit) pit=pit->prev; return tmp; } \
_Classname_##_Classobj__& operator* () const { return *(pit->pobj); } \
bool operator == (const iterator& in) const { return pit==in.pit; } \
bool operator != (const iterator& in) const { return pit!=in.pit; } \
}; \
_Classname_() { _front=_back=0; _size=0;} \
_Classname_(_Classname_& in) { \
_front=_back=0; _size=0; \
iterator it = in.begin(); \
while (it != in.end()) \
push_back(*it++); \
} \
_Classname_& operator = (_Classname_& in) { \
_front=_back=0; _size=0; \
iterator it = in.begin(); \
while (it != in.end()) \
push_back(*it++); \
return *this; \
} \
bool push_back (const _Classname_##_Classobj__& in) { \
PtrWrapper* pw = new PtrWrapper(in); \
if (!pw) return false; \
if (_size) { \
_back->next = pw; \
pw->prev = _back; \
_back = pw; \
_size++; \
} \
else { \
_front = _back = pw; \
_size++; \
} \
return true; \
} \
bool push_front (const _Classname_##_Classobj__& in) { \
PtrWrapper* pw = new PtrWrapper(in); \
if (!pw) return false; \
if (_size) { \
_front->prev = pw; \
pw->next = _front; \
_front = pw; \
_size++; \
} \
else { \
_front=_back=pw; \
_size++; \
} \
return true;\
} \
void pop_front() { /*Deletes the element at the beginning of a list */ \
if (_size==0) return; \
PtrWrapper* pw = _front->next; if (pw) pw->prev=0; \
delete _front; _front = pw; if (--_size==0) _front=_back=0; \
}\
void pop_back() { /*Deletes the element at the beginning of a list */ \
if (_size==0) return; \
PtrWrapper* pw = _back->prev; if (pw) pw->next=0; \
delete _back; _back = pw; if (--_size==0) _front=_back=0; \
}\
unsigned int size() const { return _size; } \
iterator begin() {return iterator(_front);} \
iterator end() {return iterator();} \
_Classname_##_Classobj__& back() { return *(_back->pobj); } \
_Classname_##_Classobj__& front() { return *(_front->pobj); } \
void erase( const iterator& _Where) { \
if (!(_Where.pit) || _size==0) return; \
if (_Where.pit->prev) _Where.pit->prev->next = _Where.pit->next; \
if (_Where.pit->next) _Where.pit->next->prev = _Where.pit->prev; \
if (_Where.pit==_front) _front=_front->next; \
else if (_Where.pit==_back) _back=_back->prev; \
delete _Where.pit; if (--_size==0) _front=_back=0; \
} \
~_Classname_() { while (_size) pop_front();} \
}

#endif


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru