I need an array where size is known at compile time. I know I can use std::vector or boost::array. But that's doesn't teach me how it works internally. Also I couldn't find how to add items into boost::array other than using the initializer. I have written the following code for a generic array. My intention is to get familiar with iterators, template specializations etc. Following is the code
template<typename T>
struct iterator_traits
{
typedef T value_type;
typedef T& reference_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
};
template<typename T>
struct iterator_traits<T*>
{
typedef T* value_type;
typedef T*& reference_type;
typedef T** iterator;
typedef const T const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
};
template<typename T, size_t size = 10>
class Array
{
public:
typedef typename iterator_traits<T>::value_type value_type;
typedef typename iterator_traits<T>::reference_type reference_type;
typedef typename iterator_traits<T>::iterator iterator;
typedef typename iterator_traits<T>::const_iterator const_iterator;
typedef typename iterator_traits<T>::reverse_iterator reverse_iterator;
Array() : lastIndex(0) {
}
void add(value_type element) {
if(lastIndex >= size)
throw std::out_of_range("Array is full");
array_[lastIndex++] = element;
}
reference_type at(unsigned int index){
if(index < size)
return array_[index];
else
throw std::out_of_range("Invalid index");
}
size_t capacity(){
return size;
}
iterator begin(){
return array_;
}
iterator end(){
return array_ + size;
}
const_iterator begin() const{
return array_;
}
const_iterator end() const{
return array_ + size;
}
reverse_iterator rbegin() {
return reverse_iterator(end());
}
reverse_iterator rend() {
return reverse_iterator(begin());
}
private:
value_type array_[size];
unsigned int lastIndex;
};
The above code works well. Following are my questions
1 - How can I create my array like boost::array does? Something like
Array<int> ints = { 10, 12 };
2 - Are there any pitfalls in the code?
3 - I had to use a specialization for pointer types in traits. Is that the best practice?
4 - Iterator pattern is implemented correctly or not?
Any thoughts would be great!