Click here to Skip to main content
15,893,668 members
Articles / Programming Languages / C++

Enumerator Lists and Enumerated Arrays

Rate me:
Please Sign up or sign in to vote.
4.60/5 (9 votes)
4 Oct 2011CPOL11 min read 59.2K   464   15  
Establishing a strong binding between enumerations and arrays
// This file is part of EnumeratorLib
// Copyright: Andreas Raczek
// This file is published under the The Code Project Open License (CPOL) 
// See the file "CPOL.html" for the full license governing this code. 
#pragma once

#include "enm_array_at_ct.h"
#include "enm_array_at_rt.h"

namespace lobster {

namespace enm {

template<typename list, typename value_type> struct array;

template<
    typename _parent_knot, 
    typename _parent_knot::enum_type _enum_value_any, 
    typename _value_type
>
class array<
    list<_parent_knot, _enum_value_any>, 
    _value_type
>   :
    private array<_parent_knot, _value_type>
{
    // The value stored in this node:
    _value_type _value;
  
#pragma region Friend declarations for helper classes
    // Compile-Time at<enum_type> -> method value<enum_type>();
    template<typename enum_array, typename enum_array::enum_type enum_value_test, bool b> 
        friend struct _at_ct;
        
    // Run-Time at(enum_type) -> operator[]
    template<typename enum_array, int index> 
        friend struct _at_rt;
#pragma endregion

    
public:
#pragma region Type and Compile-Time Value Definitions
    typedef typename array<_parent_knot, _value_type>       parent_array;
    typedef typename _value_type                            value_type;
    typedef typename list<_parent_knot, _enum_value_any>    enum_list;
    typedef typename enum_list::enum_type                   enum_type;
    
    static const enum_type enum_value =                     enum_list::enum_value;
    static const int size =                                 enum_list::size;
#pragma endregion
    
#pragma region Constructors
    // Standard constructor
    array() {};
    
    // Constructor for initializing from a std::pair list. It is implicitly assumed that
    // an the input_iterator value type is a std::pair or something with an identical
    // interface. Parameters are first (as in begin()) and the one after the last (as in end()) elements.
    template<typename input_iterator>
    array(input_iterator first, input_iterator last) 
    {
        for(first; first != last; first++) {
            (*this)[first->first] = first->second;
        }
    }
    
    // Constructor for initializing from a std::pair list. It is assumed that
    // an implicit cast is possible from _second_type to value_type. The array
    // containing the pairs is directly used by a neat template "trick".
    template<typename _second_type, int n>
    array(const std::pair<enum_type, _second_type> (&arr)[n]) 
    {
        // Test if the supplied array size matches the one of
        // the enumerator list
        static_assert<n == size>();
        
        for(size_t i = 0; i < n; i++) {
            (*this)[arr[i].first] = arr[i].second;
        }
    }
#pragma endregion
    
#pragma region Element Accessors
    // Compile-time element accessor
    template<enum_type enum_value_test>
    inline value_type& value() 
    {  
        return _at_ct<
            array, 
            enum_value_test, 
            equals<enum_value_test, enum_value>::value
        >::value(*this);
    }
    
    // Compile-time const accessor
    template<enum_type enum_value_test>
    inline const value_type& value() const
    {  
        return _at_ct<
            const array, 
            enum_value_test, 
            equals<enum_value_test, enum_value>::value
        >::value(*this);
    }

    // run-time element accessor
    inline value_type& operator[](enum_type enum_value_test) {
        return _at_rt<
            array,
            size-1
        >::value(*this, enum_value_test);
    }
    
    // run-time const accessor
    inline const value_type& operator[](enum_type enum_value_test) const {
        return _at_rt<
            const array,
            size-1
        >::value(*this, enum_value_test);
    }
#pragma endregion
};


// Empty enumerated array tail used to throw exceptions or cause
// compile failures when the requested enumerator
// is not part of the enumerated array.
template<
    typename _enum_type,  
    typename _value_type
>
struct array<
    tail<_enum_type>, 
    _value_type
>   
{
};


}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions