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

//  /*--------------------------------------------------------*\
//  |   Concrete Template : XYZ_Kernel_1
//  \*--------------------------------------------------------*/

#ifndef CT_XYZ_KERNEL_1
#define CT_XYZ_KERNEL_1 1

///-------------------------------------------------------------
/// Global Context ---------------------------------------------
///-------------------------------------------------------------

#include "AT/XYZ/Kernel.h"
#include "CT/DEF/Kernel_1.h"     // suppose this class is
                                 // parameterized by Item

// The following #include is in a formal comment because the names it
// brings into scope are used within formal comments in what follows.
// The compiler doesn't need them, but a human reader does need them
// in order to understand the formal comments and code in this
// component.

/*!
    #include "AT/ABC/Some_Op.h"  // suppose this utility class is
                                 // parameterized by Item
!*/

///-------------------------------------------------------------
/// Interface --------------------------------------------------
///-------------------------------------------------------------

// In this example, there is one parameter to the abstract template
// being implemented, plus three additional components used in the
// implementation.  The latter three are all declared as concrete
// template parameters, with defaults selected by the implementer
// whenever possible.  In this case, DEF_Kernel_1 has been chosed as a
// default implementation (of DEF_Kernel, assuming that's what it
// implements), and the only implementation of Representation has been
// chosed for the data representation record Rep.  A client using this
// component MUST provide actual components for all the non-default
// parameters, and MAY provide actual components as replacements for
// the default parameters.  Typically, a client will provide ONLY the
// non-default parameters.

concrete_template <
        concrete_instance class Item,
        concrete_instance utility_class ABC_Utility,
        /*!
            implements
                abstract_instance ABC_Some_Op <Item>
        !*/
        concrete_instance class DEF_Of_Item =
            DEF_Kernel_1 <Item>,
        concrete_instance class Rep =
            Representation <
		    DEF_Of_Item,
		    Integer
		>
    >
class XYZ_Kernel_1 :
    implements
        abstract_instance XYZ_Kernel <Item>,
    encapsulates
        concrete_instance Rep
{
private:

    // The following declarations are needed to give names to the
    // fields of Rep, the data representation record for an object of
    // type XYZ_Kernel_1.  These are analogous to the "data members"
    // of a class in an ordinary C++ class design.  If one of the
    // fields is itself a Record instance, then there are also
    // field_name declarations here.
    
    rep_field_name (Rep, 0, DEF_Of_Item, name_of_field_0);
    rep_field_name (Rep, 1, Integer, name_of_field_1);

    /*!

        [mathematical definitions needed to explain convention and
         correspondence and anything else that follows]
	
	convention
	    [assertion characterizing the "legal"
	     configurations of Rep, i.e., the data representation
	     record of an object of type XYZ_Kernel_1; also known as
	     the "representation invariant"]
	     
	correspondence
	    [assertion relating self (which is the abstract
	     value of an object of type XYZ_Kernel) to the
	     fields of Rep, i.e., self.name_for_field_0 and
	     self.name_for_field_1 (which comprise the
	     concrete representation of self); also known as the
	     "abstraction relation"]
    !*/

    // The following operation header and body appears ONLY if the
    // default initial value for Rep does not represent an initial
    // abstract value of an object of type XYZ_Kernel.  It is
    // analogous in functionality to the "constructor" in an ordinary
    // C++ class design -- but it is invoked "lazily", i.e., not until
    // initialization of the data representation record is no longer
    // avoidable.  This happens upon the first call to an operation
    // other than object creation (or destruction), swap (&=), or
    // Clear.  If only these standard operations are invoked on an
    // object, its data representation record is neither allocated nor
    // initalized.
    
    local_procedure_body Initialize ()
    {
	// The purpose of this code is to change one or both of
	// self[name_of_field_0] and self[name_of_field_1] from their
	// default initial values to the values needed to represent an
	// initial value of type XYZ_Kernel.
    }

    // The following operation header and body appears ONLY if the
    // representation of an object of type XYZ_Kernel_1 involves
    // explicit use of pointers, and some of the operations do dynamic
    // storage allocation.  It is analogous in functionality to the
    // "destructor" in an ordinary C++ class design -- but it is not
    // invoked unless the (lazy) call to Initialize has actually
    // occurred.
    
    local_procedure_body Finalize ()
    {
	// The purpose of this code is to reclaim any otherwise
	// unreclaimed storage that was allocated explicitly (using
	// "New") by any operation in this class.
    }

    // The following operation is a local "helper" operation that may
    // be called in the bodies of Initialize and/or Finalize and/or
    // the XYZ_Kernel operations.  There may be zero or more local
    // operations, and they may call each other (and/or themselves
    // recursively).

    local_procedure_body Local_Op (
	    // formal parameters of Local_Op, if any, with their modes
	    // and types
        )
    /*!
	requires
	    [precondition of Local_Op]
	ensures
	    [postcondition of Local_Op]
    !*/
    {
	// This code may mention any of its formal parameters, but it
	// may NOT mention self (or, by implication, any of the fields
	// of self).  Generally, some of these fields do need to be
	// manipulated by such "helper" operations, and if so they
	// must be passed as explicit parameters.
    }

public:

    // The following declaration is always needed in a concrete kernel 
    // component.  It has one parameter: the name of the concrete
    // component (class) we are in.  It implements the standard
    // operations to create (and destroy) objects of type
    // XYZ_Kernel_1, as well as swap (&=) and Clear.

    standard_concrete_operations (XYZ_Kernel_1); 

    procedure_body OpA (
	    preserves Integer i,
	    consumes Text& t,
	    produces Item& x
        )
    {
	// This code may mention the formal parameters of OpA, the
	// fields of Rep (here, self[name_of_field_0] and
	// self[name_of_field_1]), and any local objects declared in
	// the body of OpA.  It may call private local operations such
	// as Local_Op, using the syntax of a global operation call,
	// i.e., without a receiver object.  It also may call
	// ABC_Utility::Some_Op, where Some_Op is a utility operation
	// of utility_class ABC_Utility.  But it may NOT call any of
	// the XYZ_Kernel operations other than the four standard
	// operations (including itself recursively), nor may it
	// explicitly call Initialize or Finalize.
    }

    function_body Integer OpB (
	    preserves Text t,
	    preserves Item& x
        )
    {
	// This code is similar to OpA, but as a function body it must
	// return a value.
    }

};

#endif // CT_XYZ_KERNEL_1

Last modified: Thu Jan 11 17:05:57 EST 2007