// ---------------------------------------------------------------------------
// - Rupture.cpp                                                             -
// - afnix engine - rupture exception class implementation                   -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  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.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2023 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "Rupture.hpp"

namespace afnix {

  // -------------------------------------------------------------------------
  // - rupture section                                                       -
  // -------------------------------------------------------------------------
  
  // create a default rupture object

  Rupture::Rupture (void) {
    p_robj = nullptr;
  }

  // copy constructor for this returned object
  
  Rupture::Rupture (const Rupture& that) {
    that.rdlock ();
    try {
      p_robj = Object::iref (that.p_robj);
      that.unlock ();
    } catch (...) {
      that.unlock ();
      throw;
    }
  }

  // destroy this rupture object

  Rupture::~Rupture (void) {
    Object::dref (p_robj);
  }

  // assign a rupture object to this one

  Rupture& Rupture::operator = (const Rupture& that) {
    // check for self assignation
    if (this == &that) return *this;
    // lock and assign
    wrlock ();
    that.rdlock ();
    try {
      Object::iref (that.p_robj); Object::dref (p_robj); p_robj = that.p_robj;
      unlock ();
      that.unlock ();
      return *this;
    } catch (...) {
      unlock ();
      that.unlock ();
      throw;
    }
  }
  
  // return the rupture object
    
  Object* Rupture::getrobj (void) const {
    rdlock ();
    try {
      Object* result = p_robj;
      unlock ();
      return result;
    } catch (...) {
      unlock ();
      throw;
    }
  }
  
  // -------------------------------------------------------------------------
  // - return section                                                        -
  // -------------------------------------------------------------------------

  // create a return by object

  Return::Return (Object* robj) {
    p_robj = Object::iref (robj);
  }

  // copy construct this object
  
  Return::Return (const Return& that) {
    that.rdlock ();
    try {
      Rupture::operator = (that);
      that.unlock ();
    } catch (...) {
      that.unlock ();
      throw;
    }
  }

  // return the class name

  String Return::repr (void) const {
    return "Return";
  }

  // -------------------------------------------------------------------------
  // - break section                                                        -
  // -------------------------------------------------------------------------

  // create a break by object

  Break::Break (Object* robj) {
    p_robj = Object::iref (robj);
  }

  // copy construct this object
  
  Break::Break (const Break& that) {
    that.rdlock ();
    try {
      Rupture::operator = (that);
      that.unlock ();
    } catch (...) {
      that.unlock ();
      throw;
    }
  }

  // return the class name

  String Break::repr (void) const {
    return "Break";
  }

  // -------------------------------------------------------------------------
  // - continue section                                                      -
  // -------------------------------------------------------------------------

  // create a continue by object

  Continue::Continue (Object* robj) {
    p_robj = Object::iref (robj);
  }

  // copy construct this object
  
  Continue::Continue (const Continue& that) {
    that.rdlock ();
    try {
      Rupture::operator = (that);
      that.unlock ();
    } catch (...) {
      that.unlock ();
      throw;
    }
  }

  // return the class name

  String Continue::repr (void) const {
    return "Continue";
  }
}
