####################################################################################################
#
# PySpice - A Spice Package for Python
# Copyright (C) 2014 Fabrice Salvaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
####################################################################################################
""" This module provides an implementation for enumerate.
The enumerate factory :func:`EnumFactory` builds a enumerate from a list of names and assigns to
these constants a value from 0 to N-1, where N is the number of constants. For example::
enum = EnumFactory('Enum1', ('cst1', 'cst2'))
builds a enumerate with *cst1* set to 0 and *cst2* set to 1.
We can get a constant's value using an integer context like::
int(enum.cst1)
and the constant's name using::
repr(enum.cst1)
We can test constant equality using::
enum1.cst == enum2.cst
or with something that understand the *int* protocol::
enum1.cst == obj
# equivalent to
int(enum1.cst) == int(obj)
The number of constants could be retrieved with::
len(enum)
The enumerate factory :func:`ExplicitEnumFactory` is a variant that permits to specify the values of
the constants::
enum2 = ExplicitEnumFactory('Enum2', {'cst1':1, 'cst2':3})
We can test if a value is in the enumerate using::
constant_value in enum2
"""
####################################################################################################
# __all__ = ['EnumFactory', 'ExplicitEnumFactory']
####################################################################################################
####################################################################################################
####################################################################################################
####################################################################################################
[docs]class EnumConstant:
""" Define an Enum Constant """
##############################################
def __init__(self, name, value):
self._name = name
self._value = value
##############################################
def __eq__(self, other):
return self._value == int(other)
##############################################
def __int__(self):
return self._value
##############################################
def __hash__(self):
return self._value
##############################################
def __repr__(self):
return self._name
####################################################################################################
[docs]def EnumFactory(enum_name, enum_tuple):
""" Return an :class:`EnumMetaClass` instance, where *enum_name* is the class name and
*enum_tuple* is an iterable of constant's names.
"""
index = [EnumConstant(name, value) for value, name in enumerate(enum_tuple)]
obj_dict = {}
obj_dict['_size'] = len(enum_tuple)
obj_dict['_index'] = index
obj_dict.update({str(enum):enum for enum in index})
return EnumMetaClass(enum_name, (), obj_dict)
####################################################################################################
[docs]def ExplicitEnumFactory(enum_name, enum_dict):
""" Return an :class:`ExplicitEnumMetaClass` instance, where *enum_name* is the class name and
*enum_dict* is a dict of constant's names and their values.
"""
obj_dict = {}
obj_dict['constants'] = list(enum_dict.values())
for name, value in list(enum_dict.items()):
obj_dict[name] = EnumConstant(name, value)
return ExplicitEnumMetaClass(enum_name, (), obj_dict)