|
// 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
namespace lobster {
namespace enm {
#ifdef ENUMERATORLIB_VS2008HACK
template<typename enum_array, typename enum_type>
#else
template<typename enum_array>
#endif
struct default_value :
private enum_array
{
typedef typename enum_array::enum_list enum_list;
typedef typename enum_array::value_type value_type;
// If this definition is used, VC2008SP1 crashes when
// compiling the default_value<...>::value<...>()
// method template.
#ifndef ENUMERATORLIB_VS2008HACK
typedef typename enum_array::enum_type enum_type;
#endif
static const int size = enum_array::size;
#pragma region Constructors
default_value() {};
template<typename input_iterator>
default_value(input_iterator first, input_iterator last)
: enum_array(first, last)
{
}
template<typename pair_type, int n>
default_value(const pair_type(&arr)[n])
{
// Test if the supplied array size matches the one of
// the enumerator list + 1 for the default value
static_assert<n == size + 1>();
for(size_t i = 0; i < n; i++) {
(*this)[arr[i].first] = arr[i].second;
}
}
#pragma endregion
#pragma region Element accessors
// Default value storage
value_type defaultvalue;
private:
// value() helper delivering default value when bool == false
template<typename enum_array, bool b>
struct _value_helper {
typedef typename copy_const<enum_array, typename enum_array::value_type>::type value_type;
template<
typename enum_array::enum_type enum_value_test
>
inline static typename value_type& value(enum_array& /* obj */, value_type& default_value) {
return default_value;
}
};
// value() helper delivering correct value when bool == true
template<typename enum_array>
struct _value_helper<
enum_array,
true
> {
typedef typename copy_const<enum_array, typename enum_array::value_type>::type value_type;
template<
typename enum_array::enum_type enum_value_test
>
inline static value_type& value(enum_array& obj, value_type& /* default_value */) {
return obj.value<enum_value_test>();
}
};
public:
// Compile-time element accessor
template<enum_type enum_value_test>
inline value_type& value()
{
return _value_helper<
enum_array,
index_of<typename enum_array::enum_list, enum_value_test>::value >= 0
>::value<
enum_value_test
>(
(enum_array&) (*this), default_value
);
}
// Compile-time const accessor
template<enum_type enum_value_test>
inline const value_type& value() const
{
return _value_helper<
const enum_array,
index_of<typename enum_array::enum_list, enum_value_test>::value >= 0
>::value<
enum_value_test
>(
(const enum_array&) (*this), defaultvalue
);
}
// run-time element accessor override
inline value_type& operator[](enum_type enum_value_test) {
return enum_list::index_of(enum_value_test) >= 0 ?
enum_array::operator[](enum_value_test)
:
defaultvalue;
}
// run-time const accessor
inline const value_type& operator[](enum_type enum_value_test) const {
return const_cast<const value_type&>(
const_cast<default_value*> (this)->operator[](enum_value_test)
);
}
#pragma endregion
};
}
}
|
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.