#ifndef __JARRAY__ #define __JARRAY__ #include #include #include "JIO/JSerialisable.hh" #include "JTools/JMultiKey.hh" #include "JLang/JAssert.hh" #include "JLang/JClass.hh" #include "JLang/JException.hh" namespace JTOOLS { namespace { using JIO::JReader; using JIO::JWriter; using JLANG::JClass; using JLANG::JIndexOutOfRange; } /** * One dimensional array of template objects with fixed length. * The internal data structure consists of a standard C array. */ template class JArray { public: typedef const T* const_pointer; typedef T* pointer; typedef const T* const_iterator; typedef T* iterator; typedef std::reverse_iterator const_reverse_iterator; typedef std::reverse_iterator reverse_iterator; typedef T& reference; typedef const T& const_reference; typedef unsigned int size_type; typedef typename JClass::argument_type argument_type; /** * Default constructor. */ JArray() {} /** * Copy constructor. * * \param array array */ JArray(const JArray& array) { typename JArray::const_iterator in = array.begin(); for (iterator out = begin(); out != end(); ++out, ++in) *out = *in; } /** * Copy constructor. * * \param array array */ JArray(const JArray& array) { typename JArray::const_iterator in = array.begin(); for (iterator out = begin(); out != end(); ++out, ++in) *out = *in; } /** * Initialise constructor. * * \param x comma seperated argument list */ JArray(T x, ...) { va_list ap; va_start(ap, x); buffer[0] = x; // first argument for (unsigned int i = 1; i != N; ++i) { T value = va_arg(ap, T); buffer[i] = value; // next argument } va_end(ap); } /** * Constructor. * * \param key multi-dimensional key */ JArray(const JMultiKey& key) { assign(key); } /** * Constructor. * * \param key multi-dimensional key */ JArray(const JMultiKey& key) { assign(key); } const_iterator begin() const { return buffer; } const_iterator end() const { return buffer + N; } iterator begin() { return buffer; } iterator end() { return buffer + N; } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reference operator[](int index) const { return buffer[index]; } reference operator[](int index) { return buffer[index]; } /** * Get element at given index. * * \param index index * \return element at index */ const_reference at(int index) const { if (index >= 0 && index < N) return buffer[index]; else throw JIndexOutOfRange("JArray<>::at()"); } /** * Get element at given index. * * \param index index * \return element at index */ reference at(int index) { if (index >= 0 && index < N) return buffer[index]; else throw JIndexOutOfRange("JArray<>::at()"); } /** * Get pointer to data. * * \return pointer to data */ const_pointer data() const { return buffer; } /** * Get pointer to data. * * \return pointer to data */ pointer data() { return buffer; } /** * Get size of data. * * \return size of data */ size_type size() const { return N; } /** * Read template JArray from input. * * \param in JReader * \param buffer JArray * \return JReader */ friend inline JReader& operator>>(JReader& in, JArray& buffer) { for (iterator i = buffer.begin(); i != buffer.end(); ++i) in >> *i; return in; } /** * Write template JArray to output. * * \param out JWriter * \param buffer JArray * \return JWriter */ friend inline JWriter& operator<<(JWriter& out, const JArray& buffer) { for (const_iterator i = buffer.begin(); i != buffer.end(); ++i) out << *i; return out; } protected: T buffer[N]; private: /** * Assign multi-dimensional key to JArray<>. * * \param key multi-dimensional key */ template void assign(const JMultiKey& key) { buffer[N-M] = key.first; assign(key.second); } /** * Assign multi-dimensional key to JArray<>. * * \param key multi-dimensional key */ template void assign(const JMultiKey& key) { buffer[N-M] = key.first; assign(key.second); } /** * Assign one-dimensional key to JArray<>. * * \param key one-dimensional key */ void assign(const JMultiKey<1, T>& key) { buffer[N-1] = key.first; } /** * Assign one-dimensional key to JArray<>. * * \param key one-dimensional key */ void assign(const JMultiKey<1, const T>& key) { buffer[N-1] = key.first; } }; /** * One dimensional read-only array of template objects with fixed length. * The internal data structure consists of a simple pointer to the actual data. */ template class JArray { public: friend class JArray; typedef const T* const_pointer; typedef const T* const_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef const T& const_reference; typedef unsigned int size_type; /** * Constructor. * * \param array array */ template JArray(const JArray& array) : p(array.data()) { STATIC_CHECK(N <= M); } /** * Constructor. * * \param array array */ template JArray(const JArray& array) : p(array.data()) { STATIC_CHECK(N <= M); } const_iterator begin() const { return p; } const_iterator end() const { return p + N; } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } const_reference operator[](int index) const { return p[index]; } /** * Get element at given index. * * \param index index * \return element at index */ const_reference at(int index) const { if (index >= 0 && index < N) return p[index]; else throw JIndexOutOfRange("JArray<>::at()"); } /** * Get pointer to data. * * \return pointer to data */ const_pointer data() const { return p; } /** * Get size of data. * * \return size of data */ size_type size() const { return N; } /** * Rightshift array (equivalent of pointer increment). * * \return JArray */ JArray shift() const { return JArray(p + 1); } protected: const_iterator p; /** * Constructor. * * \param __p pointer to data */ JArray(const T* __p) : p(__p) {} }; } #endif