|
// 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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.