// /*-------------------------------------------------------------------*\
// | Concrete Template : Array_Kernel_2
// \*-------------------------------------------------------------------*/
#ifndef CT_ARRAY_KERNEL_2
#define CT_ARRAY_KERNEL_2 1
///------------------------------------------------------------------------
/// Global Context --------------------------------------------------------
///------------------------------------------------------------------------
#include "AT/Array/Kernel.h"
///------------------------------------------------------------------------
/// Interface -------------------------------------------------------------
///------------------------------------------------------------------------
concrete_template <
concrete_instance class Item,
concrete_instance class Rep =
Representation <
Item*,
Integer,
Integer,
Item,
Integer,
Boolean
>
>
class Array_Kernel_2 :
implements
abstract_instance Array_Kernel <Item>,
encapsulates
concrete_instance Rep
{
private:
rep_field_name (Rep, 0, Item*, items);
rep_field_name (Rep, 1, Integer, lower_bound);
rep_field_name (Rep, 2, Integer, upper_bound);
rep_field_name (Rep, 3, Item, cached_item);
rep_field_name (Rep, 4, Integer, cached_index);
rep_field_name (Rep, 5, Boolean, cache_is_full);
/*!
convention
if self.lower_bound <= self.upper_bound
then [self.items points to C++ array of Items which is
self.upper_bound - self.lower_bound + 1 entries long]
else self.items = NULL and not self.cache_is_full
correspondence
self.lb = self.lower_bound and
self.ub = self.upper_bound and
if self.cache_is_full
then self.table =
({i: integer where (self.lb <= i <= self.ub)
((i, self.items[i - self.lb]))}
- {(self.cached_index,
self.items[self.cached_index])})
union {(self.cached_index, self.cached_item)}
else self.table =
{i: integer where (self.lb <= i <= self.ub)
((i, self.items[i - self.lb]))}
!*/
local_procedure_body Initialize ()
{
self[items] = NULL;
self[lower_bound] = 1;
self[upper_bound] = 0;
}
local_procedure_body Finalize ()
{
if (self[items] != NULL)
{
delete [] self[items];
}
}
public:
standard_concrete_operations (Array_Kernel_2);
procedure_body Set_Bounds (
preserves Integer lower,
preserves Integer upper
)
{
if (self[items] != NULL)
{
delete [] self[items];
self[items] = NULL;
}
if (lower <= upper)
{
self[items] = new Item[To_int (upper - lower + 1)];
}
self[lower_bound] = lower;
self[upper_bound] = upper;
}
function_body Item& operator [] (
preserves Integer i
)
{
if (self[cache_is_full])
{
// Check for easy case: cache contains (i, ?)
if (self[cached_index] == i)
{
return self[cached_item];
}
else
{
// Empty the cache so (i, ?) can be put there
self[cached_item] &=
(self[items])[To_int (self[cached_index] -
self[lower_bound])];
}
}
// Cache is now empty; fill it with (i, ?)
self[cached_item] &= (self[items])[To_int (i - self[lower_bound])];
self[cached_index] = i;
self[cache_is_full] = true;
return self[cached_item];
}
function_body Integer Lower_Bound ()
{
return self[lower_bound];
}
function_body Integer Upper_Bound ()
{
return self[upper_bound];
}
};
#endif // CT_ARRAY_KERNEL_2
Last modified: Thu Jan 11 17:05:57 EST 2007