home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
- Chapter 29
- GENERIC PACKAGES
-
-
-
- OUR FIRST GENERIC PACKAGE
- _________________________________________________________________
-
- In the last chapter we studied the use of generic subprograms.
- This chapter will be devoted to the study of generic packages, and
- we will exhaust the topic because only procedures, functions, and
- packages can be used as generic units.
-
- Examine the file named GENPKG.ADA for our first ================
- example of a generic package. This package is GENPKG.ADA
- named EasyPkg, because it is so easy to ================
- understand, and is composed of one procedure and
- one function. The generic package begins with
- the reserved word generic, followed by two generic formal
- parameters, and the standard format for an Ada package
- specification in lines 5 through 9. The first generic formal
- parameter is a discrete type, and the second is a floating point
- type as we discussed in the last chapter.
-
- The instantiating statements are given in lines 39 and 41 of the
- main program and are no different than those used in the last
- chapter except for the first word, the reserved word package,
- because we are declaring an instance of a package in this case.
- If you replace the formal parameter types with the types declared
- in each instantiation statement, you will have a normal package
- just as we studied previously. In the case of a package, we can
- add the use clause as we have in lines 40 and 42, eliminating the
- need for the extended naming notation, commonly called the dot
- notation. After declaring a few variables to work with, we are
- ready to exercise the two procedures and functions we have
- declared. It should be clear to you that we have a procedure and
- a function in the package named Funny_Stuff, and another procedure
- and function in the package named Usual_Stuff.
-
- A fine point must be mentioned about the use clause when used with
- the generic package. It is not legal to use a use clause with the
- generic package itself. Every instantiation must explicitly give
- the extended name for the generic package. Of course this only
- occurs with nested generic packages which are the topic of the next
- example program. The use clause however, is legal for use with any
- and every instantiated copy of a generic package. The instantiated
- package's new name cannot be overloaded because it is not permitted
- to overload the name of any package.
-
-
-
-
-
- Page 29-1
-
- Chapter 29 - Generic Packages
-
- USING THE INSTANTIATED PACKAGES
- _________________________________________________________________
-
- In line 53, we call the procedure named Trade_Values, but since
- there are two procedures with this name, Ada will pick the correct
- one by comparing the types. This is our old friend called
- overloading again. In line 54, because of the types used, the
- other procedure will be used as indicated in the comments. In
- lines 55 and 56, we explicitly tell the system which overloading
- to use, but it will still check the types to see if they are
- compatible. In line 57 we tell the system to use the wrong one
- which leads to a type mismatch and a compile error, and in line 58,
- we use two different types for the parameters, which is another
- type mismatch. (Lines 57 and 58 are commented out so that we will
- not actually get the error, but you should remove the comments to
- see that the compiler does report an error.)
-
- Lines 60 through 64 give examples of proper usage of the two
- functions instantiated above and illustrate that the literals of
- type universal_real are compatible with both copies of the function
- as you would expect. The compiler uses the type of the assignment
- variable on the left hand side of the assignment statement to
- decide which overloading to use for each statement.
-
- After you spend enough time to understand this program, compile and
- execute it even though it has no output.
-
-
-
- NESTED GENERIC PACKAGES
- _________________________________________________________________
-
- The example program named NESTPKG.ADA contains ===============
- a generic package nested within another NESTPKG.ADA
- non-generic package. The outer package contains ===============
- a single procedure, and the nested generic
- package contains a single formal generic
- parameter of a floating point type, and a single function. The
- procedure and function are the same as those in the last program,
- but they are organized differently here for illustration.
-
- Note carefully that since the procedure is not in the generic part
- of the outer package, it is directly available in the same manner
- as if it were in a package without a generic part. The package
- name can be declared in a use clause which will make the
- non-generic portion of the package usable. This is not really too
- new to you because the Text_IO package we have been using
- throughout this tutorial contains several nested generic packages.
- The procedure to Put a string, as well as the procedures named
- Put_Line and New_Line are in the non-generic part of the package,
- and the procedures to output variables are nested in generic parts.
- It would be beneficial for you to take a look at the package named
- Text_IO in section 14.3.10 of the LRM. Spending a few minutes
- studying that package at this time will be time well spent.
-
- Page 29-2
-
- Chapter 29 - Generic Packages
-
-
- The executable part of the program is very simple and very similar
- to the last example program so it will be left to the student to
- study, compile, and execute this program.
-
-
-
- OBJECTS AS GENERIC FORMAL PARAMETERS
- _________________________________________________________________
-
- Examine the program named OBJGEN.ADA for an ================
- example of using objects for formal generic OBJGEN.ADA
- parameters instead of just types. In this case ================
- the number of ROWS and the number of COLUMNS
- will be part of the instantiation, and the
- resulting procedure and function will be ready to work with the
- desired size matrices. In addition, the constant named ROWS, and
- the constant named COLUMNS are initialized to the values given in
- lines 4 and 5. If a value is not given with the instantiation,
- these values will be used in much the same way that we use default
- values with a procedure or function.
-
- In this case, the package body uses the standard Text_IO package
- and outputs a string to the monitor each time one of the
- subprograms is called. This is only done to illustrate to you that
- there is nothing magic about the package Text_IO, and that it can
- be used within another package.
-
-
-
- USING THE OBJECTS
- _________________________________________________________________
-
- In line 58, the package is instantiated using the positional
- aggregate notation with values of 3 and 5 for the matrix size.
- Line 60 illustrates the use of the defaults declared in the generic
- part above, and line 61 illustrates the use of the named aggregate
- notation used during package instantiation.
-
-
-
- AN EXPORTED TYPE CAN BE USED
- _________________________________________________________________
-
- Referring back to line 8, we have the type named LOCAL_MATRIX
- declared in the package specification and therefore available to
- any calling program. If you refer to the private part of the
- package specification, you will see that the type LOCAL_MATRIX is
- declared to be a function of the formal generic objects. After we
- instantiate a copy of the package, we have the exported type
- available for use in the calling program. We use the types
- exported in lines 66 through 68 to declare a few variables, but
- even though two of the instantiations make use of the use clause,
- we must explicitly declare the desired type by using the extended
-
- Page 29-3
-
- Chapter 29 - Generic Packages
-
- naming notation. This is because the compiler has no way of
- knowing which exported type we are interested in using for each
- variable.
-
- With the above descriptions of the new concepts in this program,
- you should be able to understand the details of it. Be sure to
- compile and execute this program.
-
-
-
- A PROCEDURE AS A GENERIC PARAMETER
- _________________________________________________________________
-
- Examine the program named PROCPKG.ADA for an ===============
- example of a procedure being used as a generic PROCPKG.ADA
- formal parameter. The syntax uses the reserved ===============
- word with to begin the formal parameter in line
- 4, and the complete header for the procedure is
- given with the list of formal parameters and their types. This
- procedure can then be called from within the body of the package
- and will refer to a procedure that is actually outside of the
- generic package. Now we must define the procedure that will be
- called in order to satisfy a call to this formal parameter. We
- will see where this procedure is defined shortly.
-
- Refer to the main program where the procedure named R_Average is
- declared. It has exactly the same formal parameter structure as
- that declared in the generic formal parameter, so it can be used
- in the instantiating call in line 40. A call to the procedure in
- the generic instantiation actually results in a call back to the
- procedure in the calling program to do some calculations.
-
-
-
- WHAT CAN THIS BE USED FOR?
- _________________________________________________________________
-
- This capability gives you the ability to write a generic package
- that can be used in several places but with a slight difference in
- each place, because each instantiation can use a different
- procedure for the reference back to the calling program. This is
- simply another one of the available entities that add to the
- flexibility of Ada. After you understand the logic here, you
- should compile and execute this program.
-
-
-
- A FUNCTION AS A GENERIC PARAMETER
- _________________________________________________________________
-
- Examine the program named FUNCPKG.ADA for an example of using a
- function as a generic formal parameter. The logic is similar to
- that described in the last program except that a function is used
- for the reference back to the calling program. No further
-
- Page 29-4
-
- Chapter 29 - Generic Packages
-
- explanation will be given since it should not be ===============
- needed. It should not come as much of a FUNCPKG.ADA
- surprise to you that several procedures or ===============
- functions, or a combination of them, can be used
- as generic formal parameters. Any of the
- isolated examples can be combined as needed to achieve the desired
- goal. Nesting of generic and normal packages can be done as
- needed. It will be up to you to decide how to modularize and
- package your program to best accomplish the stated goals. Ada
- gives you many options. Be sure to compile and execute this
- program.
-
-
-
- PROGRAMMING EXERCISES
- _________________________________________________________________
-
- 1. Add an enumerated type to GENPKG.ADA, instantiate a copy of
- EasyPkg, and use it to swap some values of the enumerated
- type. You will have to supply a floating point type with the
- enumerated type when you instantiate it.
-
- 2. Convert CHARSTAK.ADA from chapter 16 of this tutorial into a
- generic package that can be used with any discrete type.
- Modify TRYSTAK.ADA from the same chapter to instantiate and
- use both an enumerated type and an INTEGER type.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 29-5