Lichen

lib/__builtins__/list.py

1022:582d834d392d
14 months ago Paul Boddie Merged changes from the value-replacement branch. value-replacement-for-wrapper
     1 #!/usr/bin/env python     2      3 """     4 List objects.     5      6 Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>     7      8 This program is free software; you can redistribute it and/or modify it under     9 the terms of the GNU General Public License as published by the Free Software    10 Foundation; either version 3 of the License, or (at your option) any later    11 version.    12     13 This program is distributed in the hope that it will be useful, but WITHOUT    14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    15 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    16 details.    17     18 You should have received a copy of the GNU General Public License along with    19 this program.  If not, see <http://www.gnu.org/licenses/>.    20 """    21     22 from __builtins__.iteration.iterator import itemiterator    23 from __builtins__.sequence import unpackable, _get_absolute_index    24 from native import list_append, list_concat, list_element, list_init, \    25                    list_len, list_nonempty, list_setelement, list_setsize    26     27 class list(unpackable):    28     29     "Implementation of list."    30     31     def __init__(self, args=None):    32     33         "Initialise the list."    34     35         # Reserve an attribute for a fragment reference along with some space    36         # for elements.    37     38         self.__data__ = list_init(args is not None and len(args) or 0)    39     40         if args is not None:    41             self.extend(args)    42     43     def __delitem__(self, index):    44     45         "Delete the item at 'index'."    46     47         length = self.__len__()    48         index = _get_absolute_index(index, length)    49         last = length - 1    50     51         while index < last:    52             self[index] = self[index + 1]    53             index += 1    54     55         # NOTE: Should truncate the allocated list after several pops.    56     57         list_setsize(self.__data__, last)    58     59     def __setslice__(self, start, end, slice): pass    60     def __delslice__(self, start, end): pass    61     62     def append(self, value):    63     64         "Append 'value' to the list."    65     66         list_append(self, value)    67     68     def insert(self, index, value):    69     70         "Insert at 'index' the given 'value'."    71     72         length = self.__len__()    73         index = _get_absolute_index(index, length)    74     75         if index == length:    76             self.append(value)    77             return    78         elif index > length:    79             raise IndexError, index    80     81         i = length - 1    82         self.append(self.__getitem__(i))    83     84         while i > index:    85             self.__setitem__(i, self.__getitem__(i - 1))    86             i -= 1    87     88         self.__setitem__(index, value)    89     90     def extend(self, iterable):    91     92         "Extend the list with the contents of 'iterable'."    93     94         for i in iterable:    95             self.append(i)    96     97     def pop(self):    98     99         "Remove the last item from the list, returning the item."   100    101         i = self[-1]   102    103         # NOTE: Should truncate the allocated list after several pops.   104    105         list_setsize(self.__data__, self.__len__() - 1)   106         return i   107    108     def reverse(self):   109    110         "Reverse the list in-place."   111    112         length = self.__len__()   113         i = 0   114         j = length - 1   115    116         while i < j:   117             item = self.__getitem__(j)   118             self.__setitem__(j, self.__getitem__(i))   119             self.__setitem__(i, item)   120             i += 1   121             j -= 1   122    123     def sort(self, cmp=None, key=None, reverse=0): pass   124    125     def __len__(self):   126    127         "Return the length of the list."   128    129         return list_len(self.__data__)   130    131     def __add__(self, other):   132    133         "Add this list to 'other', producing a new list."   134    135         l = list(self)   136         l.extend(other)   137         return l   138    139     def __iadd__(self, other):   140    141         "Concatenate 'other' to the list."   142    143         if isinstance(other, list):   144             list_concat(self, other.__data__)   145         else:   146             self.extend(other)   147         return self   148    149     def __mul__(self, other):   150    151         "Replicate this sequence 'other' times."   152    153         return self._mul(list(self), other)   154    155     def __imul__(self, other):   156    157         "Replicate this list 'other' times."   158    159         return self._mul(self, other)   160    161     def _mul(self, l, other):   162    163         "Replicate 'l' 'other' times."   164    165         copy = list(self)   166         while other > 1:   167             l.extend(copy)   168             other -= 1   169         return l   170    171     def __str__(self):   172    173         "Return a string representation."   174    175         return self._str("[", "]")   176    177     __repr__ = __str__   178    179     def __bool__(self):   180    181         "Lists are true if non-empty."   182    183         return list_nonempty(self.__data__)   184    185     def __iter__(self):   186    187         "Return an iterator."   188    189         return itemiterator(self)   190    191     # Special implementation methods.   192    193     def __get_single_item__(self, index):   194    195         "Return the item at the normalised (positive) 'index'."   196    197         self._check_index(index)   198         return list_element(self.__data__, index)   199    200     def __set_single_item__(self, index, value):   201    202         "Set at the normalised (positive) 'index' the given 'value'."   203    204         self._check_index(index)   205         return list_setelement(self.__data__, index, value)   206    207 # vim: tabstop=4 expandtab shiftwidth=4