Resolve/C++ Catalog
CT/Array/Kernel_2.h
Copyright © 2010, Reusable Software Research Group, The Ohio State University

//  /*-------------------------------------------------------------------*\
//  |   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