#if   !defined(__PERSON_HPP)
#define __PERSON_HPP

/*
  CoreLinux++ 
  Copyright (C) 1999 CoreLinux Consortium
  
   The CoreLinux++ Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CoreLinux++ Library Library is distributed in the hope that it will 
   be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  
*/   

#if   !defined(__COMMON_HPP)                     
#include <Common.hpp>          
#endif


//
// This gives our Person the types
// that is more reasonable for the
// domain.
//

DECLARE_TYPE( CORELINUX(StringUtf8), Name );
DECLARE_TYPE( CORELINUX(Long), Age );

//
// Person is a concrete non-polymorphice class that 
// examples some CoreLinux++ style and constraints. In this domain
// it is enforced that no Person can be the same as another Person.
// This is a soft approach as in a real world application uniqueness 
// in a domain would have to consider ALL persons in a domain.
//

DECLARE_CLASS( Person );

class Person
{
public:

   //
   // Public Constructors and destructors
   //

                        //
                        // Default constructor forces taking
                        // a name because what is a person 
                        // without one. The other constructors
                        // not allowed are in the protected area
                        // with assertions!
                        //

                        Person( NameCref, Age );

   virtual              ~Person( void );

   //
   // Operator overloads.
   //

            // Operator equality down to the name 

            bool  operator==( PersonCref ) const;


   //
   // Accessors
   //

            // Explicit name fetch

            NameCref    getName( void ) const;

            // Coercion name fetch

                        operator NameCref( void ) const;

            // Explicit age fetch

            AgeCref     getAge( void ) const;

            // Coercion age fetch

                        operator AgeCref( void ) const;

   //
   // Mutators
   //
            // Prefered method

            void  setAge( Age );


protected:

                        //
                        // As stated, this can't be
                        // because a Person has a Name
                        //

                        Person( void );

                        //
                        // This would violate the same
                        // person existing twice in the
                        // domain.
                        //

                        Person( PersonCref );

            // ditto

            PersonRef   operator=( PersonCref );

private:

         //
         // Use the language to enforce that the name
         // is only set once.
         //

         NameCref    theName;

         //
         // Whereas the age can change but is constrained
         // to >= 0 and and <= corelinux::Limits::LONGMAX
         //

         Age         theAge;


};

#endif // if !defined(__PERSON_HPP)

/*
   Common rcs information do not modify
   $Author: frankc $
   $Revision: 1.6 $
   $Date: 2000/02/10 14:32:20 $
   $Locker:  $
*/

