M2103-TP6-Exo-3-Corrigé

 
/**
 *
 * @file    Duree.h
 *
 * @authors M. Laporte, d. Mathieu
 *
 * @date    07/03/2008
 *
 * @version V1.0
 *
 * @brief   Declarations de la classe duree
 *
 **/
#ifndef __DUREE_H__
#define __DUREE_H__

typedef unsigned long long ULLong_t;

#include "IEditable.hpp"
#include "CException.hpp"

namespace nsUtil
{
    class Duree 
    {
      private :
        ULLong_t       myDuree;
        short unsigned mySecondes;
        short unsigned myMinutes;
        short unsigned myHeures;
        ULLong_t       myJours;
    
        void normaliser (void)                                noexcept;
    

      public :
        explicit Duree  (const ULLong_t duree = ULLong_t (0)) noexcept;

        ULLong_t getDuree (void) const                        noexcept;
        void setDuree (const ULLong_t duree = ULLong_t (0))   noexcept;

        Duree & operator ++ (void)                            noexcept;
        Duree   operator ++ (int)                             noexcept;
        Duree & operator -- (void)                  throw (CException);
        Duree   operator -- (int)                   throw (CException);

        Duree operator + (ULLong_t duree) const               noexcept;
        Duree operator - (ULLong_t duree) const     throw (CException);

        Duree & operator += (ULLong_t d)                      noexcept;
        Duree & operator -= (ULLong_t d)            throw (CException);

        Duree operator + (const Duree & d) const             noexcept;
        Duree operator - (const Duree & d) const   throw (CException);

        Duree & operator += (const Duree & d)                noexcept;
        Duree & operator -= (const Duree & d)      throw (CException);

        // Operateurs de comparaison et d'identite

        bool operator <  (const Duree & d) const              noexcept;
        bool operator == (const Duree & d) const              noexcept;

    }; // Duree
    
} // namespace nsUtil

#endif /* __DUREE_H__ */
 
/**
 *
 * @file    Duree.cpp
 *
 * @authors M. Laporte, d. Mathieu
 *
 * @date    17/03/2010
 *
 * @version V1.0
 *
 * @brief   Definition des methodes de la classe Duree
 *
 **/

#include "CException.hpp"

#include "Duree.h"
#include "CstCodErr.h"

#define CDUREE nsUtil::Duree

using namespace std;
using namespace nsUtil;

CDUREE::Duree  (const ULLong_t duree /* = UULong_t (0) */) noexcept
    : myDuree (duree) { normaliser (); }

ULLong_t CDUREE::getDuree (void) const noexcept { return myDuree; }

void CDUREE::setDuree (ULLong_t duree) noexcept 
{
    myDuree = duree;
    normaliser ();

}  // setDuree()


void CDUREE::normaliser (void) noexcept
{
      mySecondes = myDuree % 60;
      myMinutes  = myDuree / 60 % 60;
      myHeures   = myDuree / 3600 % 24;
      myJours    = myDuree / 86400;

} // normaliser()

CDUREE CDUREE::operator - (ULLong_t d) const throw (CException)
{
    if (myDuree < d)
        throw CException ("- : operation interdite",
                          KExcOpInterdite);

    return Duree (myDuree - d);

} // operator -

CDUREE::Duree CDUREE::operator + (ULLong_t d) const noexcept
{
    return Duree (myDuree + d);

} // operator +

CDUREE CDUREE::operator - (const Duree & d) const throw (CException)
{
    if (myDuree < d.myDuree)
        throw CException ("- : operation interdite",
                          KExcOpInterdite);

    return Duree (myDuree - d.myDuree);

} // operator -

CDUREE::Duree CDUREE::operator + (const Duree & d) const noexcept
{
    return Duree (myDuree + d.myDuree);

} // operator +

CDUREE & CDUREE::operator ++ (void) noexcept
{
    ++myDuree;
    normaliser ();
    return *this;

} // operator ++  pre

CDUREE CDUREE::operator ++ (int) noexcept 
{
    return Duree (myDuree++); 

} // operator ++ post

CDUREE & CDUREE::operator -- (void) throw (CException)
{
    if (myDuree == 0)
        throw CException ("-- : operation interdite",
                          KExcOpInterdite);
    --myDuree;
    normaliser ();
    return *this;

} // operator -- pre

CDUREE CDUREE::operator -- (int) throw (CException)
{
    if (myDuree == 0)
        throw CException ("-- : operation interdite",
                          KExcOpInterdite);

    return Duree (myDuree--);

} // operator -- post

CDUREE & CDUREE::operator += (ULLong_t d) noexcept
{
    myDuree += d;
    normaliser ();

    return *this;

} // operator +=

CDUREE & CDUREE::operator -= (ULLong_t d) throw (CException)
{
    if (myDuree < d)
        throw CException ("-= : operation interdite",
                          KExcOpInterdite);
    myDuree -= d;
    normaliser ();

    return *this;

} // operator -=

CDUREE & CDUREE::operator += (const Duree & d) noexcept
{
    myDuree += d.myDuree;
    normaliser ();

    return *this;

} // operator +=

CDUREE & CDUREE::operator -= (const Duree & d) throw (CException)
{
    if (myDuree < d.myDuree)
        throw CException ("-= : operation interdite",
                          KExcOpInterdite);
    myDuree -= d.myDuree;
    normaliser ();

    return *this;

} // operator -=

// Les valeurs par defaut sont rappelees en commentaires car
//   interdites

bool CDUREE::operator < (const Duree & d) const noexcept
{
    return (myDuree < d.myDuree);

} // operator <

bool CDUREE::operator == (const Duree & d) const noexcept
{
    return (myDuree == d.myDuree);

} // operator ==

#undef CDUREE

 
/**
 *
 * @file    testDuree.cpp
 *
 * @authors M. Laporte, D. Mathieu
 *
 * @date    07/12/2011
 *
 * @version V1.0
 * 
 * @brief   test de la classe Duree complete
 *
 **/
#include <iostream>
#include <exception>
#include <iomanip>   // boolalpha

#include "CException.hpp"
#include "CstCodErr.h"
#include "Duree.hpp"
#include "IEditable.hpp"

using namespace std;
using namespace rel_ops;
using namespace nsUtil;    // CException

#define classdef typedef

namespace 
{
namespace
{
    class DureeEditable : public Duree, public IEditable
    {
      protected :
        virtual std::ostream & display (std::ostream & os) const;
      public :

        explicit DureeEditable (const ULLong_t duree = ULLong_t (0))
                                                           noexcept;
        // constructeur nécessaire pour utiliser les opérateurs
        // qui renvoient
        // des Duree (un DureeEditable est un Duree, mais pas
        // l'inverse)
        DureeEditable (const Duree & duree)               noexcept;

        virtual ~DureeEditable (void)                     noexcept;

        /*     */
        DureeEditable & operator ++ (void)                            noexcept;
        DureeEditable & operator -- (void)                  throw (CException);
        DureeEditable   operator ++ (int)                             noexcept;
        DureeEditable   operator -- (int)                   throw (CException);
        DureeEditable & operator += (ULLong_t d)                      noexcept;
        DureeEditable & operator -= (ULLong_t d)            throw (CException);
        DureeEditable & operator += (const DureeEditable & d)                noexcept;
        DureeEditable & operator -= (const DureeEditable & d)      throw (CException);
        /*     */

    }; // DureeEditable

    DureeEditable::DureeEditable (const ULLong_t duree
                                           /* = ULLong_t (0) */) noexcept
        : Duree (duree) {}

    DureeEditable::DureeEditable (const Duree & duree) noexcept
        : Duree (duree) {}

    DureeEditable::~DureeEditable (void) noexcept {}

    ostream & DureeEditable::display (ostream & os) const
    {
        return
             os << '['                           << setfill (' ')
                << setw (6) << myJours    << ':' << setfill ('0')
                << setw (2) << myHeures   << ':'
                << setw (2) << myMinutes  << ':'
                << setw (2) << mySecondes << ']' << setfill (' ');

    } // display()
/*     */
    DureeEditable & DureeEditable::operator ++ (void) noexcept
    {
        return *this = Duree::operator ++ ();

    } // operator ++()

    DureeEditable & DureeEditable::operator -- (void) throw (CException)
    {
        return *this = Duree::operator -- ();

    } // operator --()

    DureeEditable DureeEditable::operator ++ (int) noexcept
    {
        return *this = Duree::operator ++ (0);

    } // operator ++()

    DureeEditable DureeEditable::operator -- (int) throw (CException)
    {
        return *this = Duree::operator -- (0);

    } // operator --()

    DureeEditable & DureeEditable::operator += (ULLong_t d) noexcept
    {
        return *this = Duree::operator += (d);

    } // operator +=()

    DureeEditable & DureeEditable::operator -= (ULLong_t d) throw (CException)
    {
        return *this = Duree::operator -= (d);

    } // operator -=()

    DureeEditable & DureeEditable::operator += (const DureeEditable & d) noexcept
    {
        return *this = Duree::operator += (d);

    } // operator +=()

    DureeEditable & DureeEditable::operator -= (const DureeEditable & d) throw (CException)
    {
        return *this = Duree::operator -= (d);

    } // operator -=()

    void testDuree_01 (void)
    {
        DureeEditable d1 (3661);
        DureeEditable d2 (2661);
        DureeEditable d3 (3661);

        cout << boolalpha;

        cout << d1 << " <  " << d2 << " : " << (d1 <  d2) << '\n';
        cout << d2 << " <  " << d1 << " : " << (d2 <  d1) << "\n\n";

        cout << d1 << " >  " << d2 << " : " << (d1 >  d2) << '\n';
        cout << d2 << " >  " << d1 << " : " << (d2 >  d1) << "\n\n";

        cout << d1 << " <= " << d2 << " : " << (d1 <= d2) << '\n';
        cout << d2 << " <= " << d1 << " : " << (d2 <= d1) << "\n\n";

        cout << d1 << " >= " << d2 << " : " << (d1 >= d2) << '\n';
        cout << d2 << " >= " << d1 << " : " << (d2 >= d1) << "\n\n";

        cout << d1 << " == " << d2 << " : " << (d1 == d2) << '\n';
        cout << d2 << " == " << d1 << " : " << (d2 == d1) << "\n\n";
        cout << d1 << " == " << d3 << " : " << (d1 == d3) << "\n\n";

        cout << d1 << " != " << d2 << " : " << (d1 != d2) << '\n';
        cout << d1 << " != " << d3 << " : " << (d1 != d3) << "\n\n";

        cout << noboolalpha;

    } // testDuree_01()

    void testDuree_02 (void)
    {
        DureeEditable d1 (3661);
        cout << "d1   = " << d1   << '\n';
        cout << "d1-- = " << d1-- << '\n';
        cout << "d1-- = " << d1-- << '\n';
        cout << "--d1 = " << --d1 << '\n';
        cout << "--d1 = " << --d1 << "\n\n";

        cout << "d1   = " << d1   << '\n';
        cout << "d1++ = " << d1++ << '\n';
        cout << "d1++ = " << d1++ << '\n';
        cout << "++d1 = " << ++d1 << '\n';
        cout << "++d1 = " << ++d1 << "\n\n";

        cout << "d1   = " << d1   << '\n';
        cout << "d1 -= 3 " << (d1 -= 3) << '\n';
        cout << "d1 += 3 " << (d1 += 3) << "\n\n";
        cout << "d1 += Duree (3) " << (d1 += Duree (3)) << "\n\n";

        d1.setDuree (0);
        cout << "d1   = " << d1   << '\n';

    } // testDuree_03()

    void testDuree_03 (void)
    {
        DureeEditable d1;
        try { d1--; }
        catch (const CException & e)
        {
            cout << "d1-- :\n" << e << '\n';
        }

        try { --d1; }
        catch (const CException & e)
        {
            cout << "--d1 :\n" << e << '\n';
        }

        try { d1 -= 1; }
        catch (const CException & e)
        {
            cout << "d1 -= 1 :\n" << e << '\n';
        }

        try { d1 -= Duree (3); }
        catch (const CException & e)
        {
            cout << "d1 -= Duree (3):\n" << e << '\n';
        }

    } // testDuree_03()

} // namespace

int main (int argc, char * argv [])
{
    if (argc != 1)
    {
        cerr << "Nombre d'arguments invalide\n"
                "Usage : testDuree\n";
        return CstErrArg;
    }
    try
    {
        /*        */

        cout << "\ntest 1\n";
        testDuree_01 ();

        /*        */
        /*        */

        cout << "\n\ntest 2\n";
        testDuree_02 ();

        /*        */
        /*        */

        cout << "\n\ntest 3\n";
        testDuree_03 ();

        /*        */

        return CstNoExc;
    }
    catch (const CException & e)
    {
        cerr << e << '\n';
        return e.getCodErr();
    }
    catch (const exception & e)
    {
        cerr << "Exception standard : " << e.what() << '\n';
        return CstExcStd;
    }
    catch (...)
    {
        cerr << "Exception inconnue\n";
        return CstExcInconnue;
    }

} // main()