diff --git a/array.hpp.html b/array.hpp.html new file mode 100644 index 0000000..1e9f7ea --- /dev/null +++ b/array.hpp.html @@ -0,0 +1,159 @@ + + +array.hpp + + + +  + +
+ + array.hpp + +

+ +

+ + +/* The following code declares class array,
* an STL container (as wrapper) for arrays of constant size.
*
* See
*      http://www.josuttis.com/cppcode
* for details and the latest version.
*
* (C) Copyright Nicolai M. Josuttis 1999.
* Permission to copy, use, modify, sell and distribute this software
* is granted provided this copyright notice appears in all copies.
* This software is provided "as is" without express or implied
* warranty, and with no claim as to its suitability for any purpose.
*
* Jul 31, 2000
*/
+#ifndef BOOST_ARRAY_HPP
+#define BOOST_ARRAY_HPP
+
+#include <cstddef>
+#include <stdexcept>
+#include <iterator>
+#include <algorithm>
+
+// BUG-FIX for compilers that don't support
+// std::size_t and std::ptrdiff_t yet
+// (such as gcc)
+#include <boost/config.hpp>
+
+namespace boost {
+
+    template<class T, std::size_t N>
+    class array {
+      public:
+        T elems[N];    // fixed-size array of elements of type T
+
+      public:
+        // type definitions
+        typedef T              value_type;
+        typedef T*             iterator;
+        typedef const T*       const_iterator;
+        typedef T&             reference;
+        typedef const T&       const_reference;
+        typedef std::size_t    size_type;
+        typedef std::ptrdiff_t difference_type;
+    
+        // iterator support
+        iterator begin() { return elems; }
+        const_iterator begin() const { return elems; }
+        iterator end() { return elems+N; }
+        const_iterator end() const { return elems+N; }
+    
+        // reverse iterator support
+        typedef std::reverse_iterator<iterator> reverse_iterator;
+        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+        reverse_iterator rbegin() { return reverse_iterator(end()); }
+        const_reverse_iterator rbegin() const {
+            return const_reverse_iterator(end());
+        }
+        reverse_iterator rend() { return reverse_iterator(begin()); }
+        const_reverse_iterator rend() const {
+            return const_reverse_iterator(begin());
+        }
+
+        // operator[]
+        reference operator[](size_type i) { return elems[i]; }
+        const_reference operator[](size_type i) const { return elems[i]; }
+
+        // at() with range check
+        // note: rangecheck() is public because we have implemented array
+        //       as aggregate, which forbids non-public members
+        void rangecheck (size_type i) const {
+            if (i >= size()) { throw std::range_error("array"); }
+        }
+        reference at(size_type i) { rangecheck(i); return elems[i]; }
+        const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
+    
+        // front() and back()
+        reference front() { return elems[0]; }
+        const_reference front() const { return elems[0]; }
+        reference back() { return elems[N-1]; }
+        const_reference back() const { return elems[N-1]; }
+
+        // size is constant
+        static size_type size() { return N; }
+        static bool empty() { return false; }
+        static size_type max_size() { return N; }
+        enum { static_size = N };
+
+        // swap (note: linear complexity)
+        void swap (array& y) {
+            std::swap_ranges(begin(),end(),y.begin());
+        }
+
+        // direct access to data
+        const T* data() const { return elems; }
+
+        // assignment with type conversion
+        //template <typename T2>
+        //T& operator= (const array<T2,N>& rhs) {
+        //    std::copy (begin(),end(),rhs.begin());
+        //}
+    };
+
+    // comparisons
+    template<class T, std::size_t N>
+    bool operator== (const array<T,N>& x, const array<T,N>& y) {
+        return std::equal(x.begin(), x.end(), y.begin());
+    }
+    template<class T, std::size_t N>
+    bool operator< (const array<T,N>& x, const array<T,N>& y) {
+        return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
+    }
+    template<class T, std::size_t N>
+    bool operator!= (const array<T,N>& x, const array<T,N>& y) {
+        return !(x==y);
+    }
+    template<class T, std::size_t N>
+    bool operator> (const array<T,N>& x, const array<T,N>& y) {
+        return y<x;
+    }
+    template<class T, std::size_t N>
+    bool operator<= (const array<T,N>& x, const array<T,N>& y) {
+        return !(y<x);
+    }
+    template<class T, std::size_t N>
+    bool operator>= (const array<T,N>& x, const array<T,N>& y) {
+        return !(x<y);
+    }
+
+    // global swap()
+    template<class T, std::size_t N>
+    inline void swap (const array<T,N>& x, const array<T,N>& y) {
+        x.swap(y);
+    }
+
+} /* namespace boost */
+
+#endif /*BOOST_ARRAY_HPP*/
+
+
+ + diff --git a/array.htm b/array.htm new file mode 100644 index 0000000..084b246 --- /dev/null +++ b/array.htm @@ -0,0 +1,314 @@ + + + + + + +array.hpp, an STL Array Wrapper + + +  + + + + +
Class + array, an STL Container (as + Wrapper) for Arrays of Constant Size
+

The C++ Standard Template + Library STL as part of the C++ Standard Library provides a framework for processing + algorithms on different kind of containers. However, ordinary arrays don't provide + the interface of STL containers (although, they provide the iterator interface + of STL containers). +

As replacement for ordinary + arrays, the STL provides class vector<>. + However, vector<> provides + the semantics of dynamic arrays. Thus, it manages data to be able to change + the number of elements. This results in some overhead in case only arrays with + static size are needed. +

In his book, Generic + Programming and the STL, Matthew H. Austern introduces a useful wrapper + class for ordinary arrays with static size, called block. + It is safer and has no worse performance than ordinary arrays. In The C++ + Programming Language, 3rd edition, Bjarne Stroustrup introduces a similar + class, called c_array, + which I (Nicolai Josuttis) present slightly + modified in my book The C++ Standard Library - A Tutorial and Reference, + called carray. This is + the essence of these approaches spiced with many feedback from boost. +

After considering different + names, we decided to name this class simply array. +

The class provides the + following interface: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Types:
value_typetype of the elements
iteratortype of the iterator + (random-access iterator)
const_iteratortype of iterator that + considers elements as being constant
referencetype of element reference
const_referencetype of element reference + that considers elements as being constant
size_typetype for signed size + values
difference_typetype for unsigned + difference values
Operations:
+

array<type,num>

+
default constructor, + creates array of num + element of type, see + comment below
array<type,num>(a)copy constructor, + copies all elements of a + (a must have same + type + and num)
operator=assignment, assigns + all elements
begin()returns iterator for + the first element
end()returns iterator for + position after the last element
rbegin()returns reverse iterator + for position of first element of reverse iteration
rend()returns reverse iterator + for posistion behind last element of reverese iteration
operator[i]returns element with + index i (no range + checking)
at(i)returns element with + index i (throw std::range_error + if i is not valid)
front()returns first element + (caller has to ensure that it exists)
back()returns last element + (caller has to ensure that it exists)
data()returns raw element + array for read-only element access
size()returns number of + elements
empty()returns whether array + is empty
max_size()returns maximum possible + number of elements (same as size())
swap(a)swap elements with + array a
==, + !=checks for equality
<, + <=, >, + >=compares array
Values: 
static_sizeyields size at compile + time
+

Class array fulfills most + but not all of the requirements of "reversible containers" (see Section + 23.1, [lib.container.requirements] of the C++ Standard). The reasons array is + not an reversible STL container is because:
+ - No constructors are provided
+ - Elements may have an indetermined initial value (see below)
+ - swap() has no constant complexity
+ - size() is always constant, based on the second template argument of the type
+ - The container provides no allocator support
+

It doesn't fulfill the + requirements of a "sequence" (see Section 23.1.1, [lib.sequence.reqmts] + of the C++ Standard), except that
+ - front() and back() are provided
+ - operator[] and at() are provided
+

Regarding the constructors + there was an important design tradeoff: We could implement array as an "aggregate" + (see Section 8.5.1, [dcl.init.aggr], of the C++ Standard). This would mean:

+ +

The current implementation + useus this approach. However, being able to have indetermined initial values + is a big drawback. So, please give me some feedback, how useful you consider + this feature to be. This leads to the list of Open issues: +

+

I'd appreciate any constructive feedback. + Please note: I don't have time to read all boost mails. Thus, to make sure + that feedback arrives me, please send me a copy of each mail regarding this + class. +

The code is provided "as is" without + expressed or implied warranty. +

array.hpp, the implementation + of array<>: +

  • + as HTML file
  • +
  • + as plain file
  • +

    Simple Example for using array<>: +

  • + as HTML file
  • +
  • + as plain file
  • +

    Another Example for using array<>: +

  • + as HTML file
  • +
  • + as plain file
  • +

    A third Example for using array<>: +

  • + as HTML file
  • +
  • + as plain file
  • +

    An Example for using arrays + of arrays: +

  • as HTML + file
  • +
  • as plain file
  • +

    An Example for testing other operations + of array<>: +

  • as HTML + file
  • +
  • as plain file
  • +

    All files +

  • as ZIP file + (24KB)
  • +
  • as TGZ file + (13KB)
    +
    + To find more details about using ordinary arrays in C++ and the framework of + the STL, see e.g.

    +      The C++ + Standard Library - A Tutorial and Reference
    +      by Nicolai + M. Josuttis

    +      Addison Wesley Longman, 1999

    +      ISBN 0-201-37926-0

    +
  • +

    Home + Page of Nicolai Josuttis
    +  
    + + diff --git a/array1.cpp b/array1.cpp new file mode 100644 index 0000000..d04052c --- /dev/null +++ b/array1.cpp @@ -0,0 +1,46 @@ +/* simple example for using class array<> + */ +#include +#include + +int main() +{ + // define special type name + typedef boost::array Array; + + // create and initialize an array + Array a = { { 42 } }; + + // access elements + for (unsigned i=1; i + +array1.cpp + + + +  + +
    + + array1.cpp + +

    + +

    + + +/* simple example for using class array<>
    */
    +#include <iostream>
    +#include <boost/array.hpp>
    +
    +int main()
    +{
    +    // define special type name
    +    typedef boost::array<float,6> Array;
    +
    +    // create and initialize an array
    +    Array a = { { 42 } };
    +
    +    // access elements
    +    for (unsigned i=1; i<a.size(); ++i) {
    +        a[i] = a[i-1]+1;
    +    }
    +
    +    // use some common STL container operations
    +    std::cout << "size:     " << a.size() << std::endl;
    +    std::cout << "empty:    " << std::boolalpha << a.empty() << std::endl;
    +    std::cout << "max_size: " << a.max_size() << std::endl;
    +    std::cout << "front:    " << a.front() << std::endl;
    +    std::cout << "back:     " << a.back() << std::endl;
    +    std::cout << "elems:    ";
    +
    +    // iterate through all elements
    +    for (Array::const_iterator pos=a.begin(); pos<a.end(); ++pos) {
    +        std::cout << *pos << ' ';
    +    }
    +    std::cout << std::endl;
    +
    +    // check copy constructor and assignment operator
    +    Array b(a);
    +    Array c;
    +    c = a;
    +    if (a==b && a==c) {
    +        std::cout << "copy construction and copy assignment are OK"
    +           << std::endl;
    +    }
    +    else {
    +        std::cout << "copy construction and copy assignment are OK"
    +           << std::endl;
    +    }
    +}
    +
    +
    +
    + + diff --git a/array2.cpp b/array2.cpp new file mode 100644 index 0000000..bc0045e --- /dev/null +++ b/array2.cpp @@ -0,0 +1,33 @@ +/* example for using class array<> + */ +#include +#include +#include +#include "print.hpp" +using namespace std; +using namespace boost; + +int main() +{ + // create and initialize array + array a = { { 1, 2, 3, 4, 5 } }; + + PRINT_ELEMENTS(a); + + // modify elements directly + for (unsigned i=0; i()); // operation + PRINT_ELEMENTS(a); +} + diff --git a/array2.cpp.html b/array2.cpp.html new file mode 100644 index 0000000..fe5a740 --- /dev/null +++ b/array2.cpp.html @@ -0,0 +1,54 @@ + + +array2.cpp + + + +  + +
    + + array2.cpp + +

    + +

    + + +/* example for using class array<>
    */
    +#include <algorithm>
    +#include <functional>
    +#include <boost/array.hpp>
    +#include "print.hpp"
    +using namespace std;
    +using namespace boost;
    +
    +int main()
    +{
    +    // create and initialize array
    +    array<int,10> a = { { 1, 2, 3, 4, 5 } };
    +
    +    PRINT_ELEMENTS(a);
    +
    +    // modify elements directly
    +    for (unsigned i=0; i<a.size(); ++i) {
    +        ++a[i];
    +    }
    +    PRINT_ELEMENTS(a);
    +
    +    // change order using an STL algorithm
    +    reverse(a.begin(),a.end());
    +    PRINT_ELEMENTS(a);
    +
    +    // negate elements using STL framework
    +    transform(a.begin(),a.end(),    // source
    +              a.begin(),            // destination
    +              negate<int>());       // operation
    +    PRINT_ELEMENTS(a);
    +}
    +
    +
    +
    + + diff --git a/array3.cpp b/array3.cpp new file mode 100644 index 0000000..9c89caf --- /dev/null +++ b/array3.cpp @@ -0,0 +1,48 @@ +/* example for using class array<> + */ +#include +#include +#include + +template +void print_elements (const T& x); + +int main() +{ + // create array of four seasons + boost::array seasons = { + { "spring", "summer", "autumn", "winter" } + }; + + // copy and change order + boost::array seasons_orig = seasons; + for (unsigned i=seasons.size()-1; i>0; --i) { + swap(seasons.at(i),seasons.at((i+1)%seasons.size())); + } + + std::cout << "one way: "; + print_elements(seasons); + + // try swap() + std::cout << "other way: "; + swap(seasons,seasons_orig); + print_elements(seasons); + + // try reverse iterators + std::cout << "reverse: "; + for (boost::array::reverse_iterator pos + =seasons.rbegin(); pos +void print_elements (const T& x) +{ + for (unsigned i=0; i + +array3.cpp + + + +  + +
    + + array3.cpp + +

    + +

    + + +/* example for using class array<>
    */
    +#include <string>
    +#include <iostream>
    +#include <boost/array.hpp>
    +
    +template <class T>
    +void print_elements (const T& x);
    +
    +int main()
    +{
    +    // create array of four seasons
    +    boost::array<std::string,4> seasons = {
    +        { "spring", "summer", "autumn", "winter" }
    +    };
    +
    +    // copy and change order
    +    boost::array<std::string,4> seasons_orig = seasons;
    +    for (unsigned i=seasons.size()-1; i>0; --i) {
    +        swap(seasons.at(i),seasons.at((i+1)%seasons.size()));
    +    }
    +
    +    std::cout << "one way:   ";
    +    print_elements(seasons);
    +
    +    // try swap()
    +    std::cout << "other way: ";
    +    swap(seasons,seasons_orig);
    +    print_elements(seasons);
    +
    +    // try reverse iterators
    +    std::cout << "reverse:   ";
    +    for (boost::array<std::string,4>::reverse_iterator pos
    +           =seasons.rbegin(); pos<seasons.rend(); ++pos) {
    +        std::cout << " " << *pos;
    +    }
    +    std::cout << std::endl;
    +}
    +
    +template <class T>
    +void print_elements (const T& x)
    +{
    +    for (unsigned i=0; i<x.size(); ++i) {
    +        std::cout << " " << x[i];
    +    }
    +    std::cout << std::endl;
    +}
    +
    +
    +
    + + diff --git a/array4.cpp b/array4.cpp new file mode 100644 index 0000000..0820cde --- /dev/null +++ b/array4.cpp @@ -0,0 +1,36 @@ +/* example for using class array<> + */ +#include +#include +#include +#include +#include + +int main() +{ + // array of arrays of seasons + boost::array,2> seasons_i18n = { + { { { "spring", "summer", "autumn", "winter", } }, + { { "Fruehling", "Sommer", "Herbst", "Winter" } } + } + }; + + // for any array of seasons print seasons + for (unsigned i=0; i seasons = seasons_i18n[i]; + for (unsigned j=0; j + +array4.cpp + + + +  + +
    + + array4.cpp + +

    + +

    + + +/* example for using class array<>
    */
    +#include <algorithm>
    +#include <functional>
    +#include <string>
    +#include <iostream>
    +#include <boost/array.hpp>
    +
    +int main()
    +{
    +    // array of arrays of seasons
    +    boost::array<boost::array<std::string,4>,2> seasons_i18n = {
    +        { { { "spring", "summer", "autumn", "winter", } },
    +          { { "Fruehling", "Sommer", "Herbst", "Winter" } }
    +        }
    +    };
    +
    +    // for any array of seasons print seasons
    +    for (unsigned i=0; i<seasons_i18n.size(); ++i) {
    +        boost::array<std::string,4> seasons = seasons_i18n[i];
    +        for (unsigned j=0; j<seasons.size(); ++j) {
    +            std::cout << seasons[j] << " ";
    +        }
    +        std::cout << std::endl;
    +    }
    +
    +    // print first element of first array
    +    std::cout << "first element of first array: "
    +              << seasons_i18n[0][0] << std::endl;
    +
    +    // print last element of last array
    +    std::cout << "last element of last array: "
    +              << seasons_i18n[seasons_i18n.size()-1][seasons_i18n[0].size()-1]
    +       << std::endl;
    +}
    +
    +
    +
    + + diff --git a/array5.cpp b/array5.cpp new file mode 100644 index 0000000..0f932c2 --- /dev/null +++ b/array5.cpp @@ -0,0 +1,63 @@ +/* simple example for using class array<> + */ +#include +#include + +template +void test_static_size (const T& cont) +{ + int tmp[T::static_size]; + for (unsigned i=0; i Array; + + // create and initialize an array + const Array a = { { 42.42 } }; + + // use some common STL container operations + std::cout << "static_size: " << a.size() << std::endl; + std::cout << "size: " << a.size() << std::endl; + std::cout << "empty: " << std::boolalpha << a.empty() << std::endl; + std::cout << "max_size: " << a.max_size() << std::endl; + std::cout << "front: " << a.front() << std::endl; + std::cout << "back: " << a.back() << std::endl; + std::cout << "[0]: " << a[0] << std::endl; + std::cout << "elems: "; + + // iterate through all elements + for (Array::const_iterator pos=a.begin(); pos DArray; + //typedef boost::array IArray; + //IArray ia = { { 1, 2, 3, 4, 5, 6 } }; + //DArray da; + //da.assign(ia); +} + diff --git a/array5.cpp.html b/array5.cpp.html new file mode 100644 index 0000000..3428a16 --- /dev/null +++ b/array5.cpp.html @@ -0,0 +1,84 @@ + + +array5.cpp + + + +  + +
    + + array5.cpp + +

    + +

    + + +/* simple example for using class array<>
    */
    +#include <iostream>
    +#include <boost/array.hpp>
    +
    +template <typename T>
    +void test_static_size (const T& cont)
    +{
    +    int tmp[T::static_size];
    +    for (unsigned i=0; i<T::static_size; ++i) {
    +        tmp[i] = int(cont[i]);
    +    }
    +    for (unsigned i=0; i<T::static_size; ++i) {
    +        std::cout << tmp[i] << ' ';
    +    }
    +    std::cout << std::endl;
    +}
    +
    +int main()
    +{
    +    // define special type name
    +    typedef boost::array<float,6> Array;
    +
    +    // create and initialize an array
    +    const Array a = { { 42.42 } };
    +
    +    // use some common STL container operations
    +    std::cout << "static_size: " << a.size() << std::endl;
    +    std::cout << "size:        " << a.size() << std::endl;
    +    std::cout << "empty:       " << std::boolalpha << a.empty() << std::endl;
    +    std::cout << "max_size:    " << a.max_size() << std::endl;
    +    std::cout << "front:       " << a.front() << std::endl;
    +    std::cout << "back:        " << a.back() << std::endl;
    +    std::cout << "[0]:         " << a[0] << std::endl;
    +    std::cout << "elems:       ";
    +
    +    // iterate through all elements
    +    for (Array::const_iterator pos=a.begin(); pos<a.end(); ++pos) {
    +        std::cout << *pos << ' ';
    +    }
    +    std::cout << std::endl;
    +    test_static_size(a);
    +
    +    // check copy constructor and assignment operator
    +    Array b(a);
    +    Array c;
    +    c = a;
    +    if (a==b && a==c) {
    +        std::cout << "copy construction and copy assignment are OK"
    +           << std::endl;
    +    }
    +    else {
    +        std::cout << "copy construction and copy assignment are OK"
    +           << std::endl;
    +    }
    +
    +    //typedef boost::array<double,6> DArray;
    +    //typedef boost::array<int,6> IArray;
    +    //IArray ia = { { 1, 2, 3, 4, 5, 6 } };
    +    //DArray da;
    +    //da.assign(ia);
    +}
    +
    +
    +
    + + diff --git a/print.hpp.html b/print.hpp.html new file mode 100644 index 0000000..c0aabaa --- /dev/null +++ b/print.hpp.html @@ -0,0 +1,48 @@ + + +PRINT_ELEMENTS() + + + +  + +
    + + PRINT_ELEMENTS() + +

    + + + The following code example is taken from the book
    + + The C++ Standard Library - A Tutorial and Reference
    + by Nicolai M. Josuttis, Addison-Wesley, 1999
    + + © Copyright Nicolai M. Josuttis 1999
    +
    + +

    + + +#include <iostream>
    +
    +/* PRINT_ELEMENTS()
    * - prints optional C-string optcstr followed by
    * - all elements of the collection coll
    * - separated by spaces
    */
    +template <class T>
    +inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="")
    +{
    +    typename T::const_iterator pos;
    +
    +    std::cout << optcstr;
    +    for (pos=coll.begin(); pos!=coll.end(); ++pos) {
    +        std::cout << *pos << ' ';
    +    }
    +    std::cout << std::endl;
    +}
    +
    +
    + +