Commit a7a70bb2 authored by thomas.forbriger's avatar thomas.forbriger Committed by thomas.forbriger
Browse files

introduced exceptions and externally managed memory

This is a legacy commit from before 2015-03-01.
It may be incomplete as well as inconsistent.
See COPYING.legacy and README.history for details.


SVN Path:     http://gpitrsvn.gpi.uni-karlsruhe.de/repos/TFSoftware/trunk
SVN Revision: 1182
SVN UUID:     67feda4a-a26e-11df-9d6e-31afc202ad0c
parent 0c0ab980
# this is <Makefile>
# ----------------------------------------------------------------------------
# $Id: Makefile,v 1.3 2002-12-08 22:28:05 forbrig Exp $
# $Id: Makefile,v 1.4 2002-12-10 19:30:06 forbrig Exp $
#
# Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
#
......@@ -51,7 +51,7 @@ HEADERS=$(shell find . -name \*.h)
# in the binary version of the library
# (see below for the configuration of a preinstantiated version of template
# code)
SRC=
SRC=lib/error.cc
# test programs are placed in a subdirectory
TESTS=$(wildcard tests/*.cc)
# whereever we find a README, we will use it
......@@ -181,9 +181,11 @@ binarray%.o: binarray.cc macro%.xxx
#----------------------------------------------------------------------
# create the binary library
# -------------------------
LIBOBS=$(ALLOBS) $(patsubst %.cc,%.o,$(SRC))
LIBOBS=$(patsubst %.cc,%.o,$(SRC))
libcontxx.a: install-include $(ALLOBS)
ar rcv $@ $(ALLBOS)
libaff.a: install-include $(LIBOBS)
ar rcv $@ $(LIBOBS)
ranlib $@
cp -vpf $@ $(LIBINSTALLPATH)
......
......@@ -3,7 +3,7 @@
*
* ----------------------------------------------------------------------------
*
* $Id: README,v 1.3 2002-12-08 22:28:05 forbrig Exp $
* $Id: README,v 1.4 2002-12-10 19:30:06 forbrig Exp $
*
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
*
......@@ -48,7 +48,7 @@ namespace aff {
\since December 2002
\date December 2002
\version V1.0
$Id: README,v 1.3 2002-12-08 22:28:05 forbrig Exp $
$Id: README,v 1.4 2002-12-10 19:30:06 forbrig Exp $
Contents of this page:
- \ref sec_main_aims
......@@ -240,6 +240,7 @@ $Id: README,v 1.3 2002-12-08 22:28:05 forbrig Exp $
The inclusion of header files is controlled by a set of preprocessor macros.
\sa AFF_PREBUILT
\sa AFF_INDEXCHECK
\sa AFF_NO_DEFINITIONS
\sa AFF_COMPILING_LIBRARY
\sa DOXYGEN_MUST_SKIP_THIS
......
/*! \file error.cc
* \brief exceptions and error handling macros (implementation)
*
* ----------------------------------------------------------------------------
*
* $Id: error.cc,v 1.1 2002-12-10 19:30:07 forbrig Exp $
* \author Thomas Forbriger
* \date 27/11/2002
*
* exceptions and error handling macros (implementation)
*
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
*
* REVISIONS and CHANGES
* - 10/12/2002 V1.0 copied from libtfxx
*
* ============================================================================
*/
#define AFF_ERROR_CC_VERSION \
"AFF_ERROR_CC V1.0 "
#define AFF_ERROR_CC_CVSID \
"$Id: error.cc,v 1.1 2002-12-10 19:30:07 forbrig Exp $"
#include <iostream>
#include <aff/lib/error.h>
using std::cerr;
using std::endl;
namespace aff {
//! initialize and instantiate
bool Exception::Mreport_on_construct=true;
//! construct from nothing
Exception::Exception():
Mmessage(NULL), Mfile(NULL), Mline(0), Mcondition(NULL)
{ if (Mreport_on_construct) { report(); } }
//! construct with message
Exception::Exception(const char* message):
Mmessage(message), Mfile(NULL), Mline(0), Mcondition(NULL)
{ if (Mreport_on_construct) { report(); } }
//! construct with message and file info
Exception::Exception(const char* message,
const char* condition):
Mmessage(message), Mfile(NULL), Mline(0), Mcondition(condition)
{ if (Mreport_on_construct) { report(); } }
//! construct with message and file info
Exception::Exception(const char* message,
const char* file,
const int& line):
Mmessage(message), Mfile(file), Mline(line), Mcondition(NULL)
{ if (Mreport_on_construct) { report(); } }
//! construct with message and file info and condition
Exception::Exception(const char* message,
const char* file,
const int& line,
const char* condition):
Mmessage(message), Mfile(file), Mline(line), Mcondition(condition)
{ if (Mreport_on_construct) { report(); } }
//! switch on
void Exception::report_on_construct()
{
Mreport_on_construct=true;
}
//! switch off
void Exception::dont_report_on_construct()
{
Mreport_on_construct=false;
}
//! report
void Exception::report() const
{
base_report();
}
//! report
void Exception::base_report() const
{
cerr << "Exception report:" << endl;
if (Mmessage==NULL)
{
cerr << " No message" << endl;
}
else
{
cerr << " message: " << Mmessage << endl;
}
if (Mfile!=NULL)
{
cerr << " triggered in \"" << Mfile << "\" at line #" << Mline << endl;
}
if (Mcondition!=NULL)
{
cerr << " by condition:" << endl
<< " \"" << Mcondition << "\"" << endl;
}
}
} // namespace aff
/* ----- END OF error.cc ----- */
/*! \file error.h
* \brief exceptions and error handling macros (prototypes)
*
* ----------------------------------------------------------------------------
*
* $Id: error.h,v 1.1 2002-12-10 19:30:07 forbrig Exp $
* \author Thomas Forbriger
* \date 27/11/2002
*
* exceptions and error handling macros (prototypes)
*
* \sa aff::Exception
*
* \note
* This file is automatically included through array.h or binarray.h
*
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
*
* REVISIONS and CHANGES
* - 10/12/2002 V1.0 copied from libtfxx
*
* ============================================================================
*/
// include guard
#ifndef AFF_ERROR_H_VERSION
#define AFF_ERROR_H_VERSION \
"AFF_ERROR_H V1.0 "
#define AFF_ERROR_H_CVSID \
"$Id: error.h,v 1.1 2002-12-10 19:30:07 forbrig Exp $"
namespace aff {
/*! \defgroup group_error Error handling module
*/
/*! \brief Base class for exceptions
*
* This is an exception base class. It holds some information about the
* reason for throwing the exception. The information is printed to cerr
* through function report(). This function may be overloaded by a derived
* type. But its functionality is still accessible through base_report().
*
* The standard behaviour is to print ou the message during object
* initialization. If you don't like this, call dont_report_on_construct().
*
* \ingroup group_error
* \sa AFF_Xassert
* \sa AFF_assert
* \sa AFF_abort
*/
class Exception
{
public:
//! Creates exception with no explaning comments
Exception();
//! Creates an exception with an explanation message
Exception(const char* message);
//! Creates an exception with message and failed assertion
Exception(const char* message,
const char* condition);
//! Create with message, failed assertion, and code position
Exception(const char* message,
const char* file,
const int& line,
const char* condition);
//! Create with message and code position
Exception(const char* message,
const char* file,
const int& line);
//! Screen report
virtual void report() const;
//! Issue a screen report on construction of exception
static void report_on_construct();
//! Issue NO screen report on construction of exception
static void dont_report_on_construct();
private:
//! Screen report
void base_report() const;
//! Shall we print to cerr at construction time?
static bool Mreport_on_construct;
//! pointer to message string
const char* Mmessage;
//! pointer to file name string
const char* Mfile;
//! pointer to line number in source file
const int& Mline;
//! pointer to assertion condition text string
const char* Mcondition;
}; // class Exception
} // namespace aff
/*======================================================================*/
//
// preprocessor macros
// ===================
/*! \brief Check an assertion and report by throwing an exception
*
* \ingroup group_error
* \param C assert condition
* \param M message of type char*
* \param E exception class to throw
*/
#define AFF_Xassert(C,M,E) \
if (!(C)) { throw( E ( M , __FILE__, __LINE__, #C )); }
/*! \brief Check an assertion and report by throwing an exception
*
* \ingroup group_error
* \param C assert condition
* \param M message of type char*
*/
#define AFF_assert(C,M) AFF_Xassert( C , M , aff::Exception )
/*! \brief Abort and give a message
*
* \ingroup group_error
* \param M message of type char*
* \param E exception class to throw
*/
#define AFF_abort(M) \
throw( aff::Exception ( M , __FILE__, __LINE__ ))
#endif // AFF_ERROR_H_VERSION (includeguard)
/* ----- END OF error.h ----- */
......@@ -3,16 +3,14 @@
*
* ----------------------------------------------------------------------------
*
* $Id: sharedheap.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $
* $Id: sharedheap.h,v 1.3 2002-12-10 19:30:07 forbrig Exp $
* \author Thomas Forbriger
* \since 08/12/2002
*
* shared heap representation (prototypes)
* \sa aff::SharedHeap
*
* \note
* Usually you will not include this header directly. It is included via
* array.h or binarray.h
* \sa aff::SHeap
* \sa aff::AllocException
*
* Copyright (c) 2002 by Thomas Forbriger (IMG Frankfurt)
*
......@@ -28,7 +26,7 @@
#define AFF_SHAREDHEAP_H_VERSION \
"AFF_SHAREDHEAP_H V1.2 "
#define AFF_SHAREDHEAP_H_CVSID \
"$Id: sharedheap.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $"
"$Id: sharedheap.h,v 1.3 2002-12-10 19:30:07 forbrig Exp $"
#include<new>
#include<aff/lib/types.h>
......@@ -46,22 +44,57 @@ namespace prebuilt {
using namespace aff::util;
#endif
// namespace {
//! A structure to be shared between different SharedHeap.
template<typename T>
struct SHeap
{
//! Allocate memory on heap.
SHeap(const Tsize& size);
/*! \brief Exception thrown in case of allocation error
*
* \sa aff::Exception
*/
class AllocException:
public Exception
{
public:
//! take number of requested elements and their size
AllocException(const Tsize& n, const Tsize& size);
//! Screen report
virtual void report() const;
private:
//! members to remember
Tsize Mn, Msize;
}; // class AllocException
/*----------------------------------------------------------------------*/
/*! A structure to be shared between different SharedHeap.
*
* This is the core part of represented shared heap. Only objects of this
* class allocate and delete memory. The SharedHeap representation has holds
* a pointer to an instance of this struct. The representation is
* responsible for doing the reference counting by incrementing and
* decrementing Mnref and to call the destructor of SHeap once the reference
* count drops to zero. The actual deallocation of the memory block used for
* the array is, however, done within the destructor of SHeap.
*
* For arrays taken from Fortran code we use a flag \c Mextern. If it is
* true, this indicates that memory should neither be allocated be the
* constructor nor given free by the destructor.
*/
template<typename T>
struct SHeap
{
//! Allocate memory on heap.
SHeap(const Tsize& size);
//! Take memory reference from elsewhere
SHeap(T* pointer, const Tsize& size);
//! Free heap memory.
~SHeap();
//! Free heap memory.
~SHeap();
T* Mheap; //!< shared raw array on heap
Tsize Msize; //!< size (number of elements) of array
Tsize Mnref; //!< number of referencing instances
}; // struct SHeap
// } // namespace
T* Mheap; //!< shared raw array on heap
Tsize Msize; //!< size (number of elements) of array
Tsize Mnref; //!< number of referencing instances
bool Mextern; //!< true if memory allocation is handled elsewhere
}; // struct SHeap
/*----------------------------------------------------------------------*/
/*! \brief A template class to share heap memory for different array
* projections.
......@@ -89,6 +122,8 @@ namespace prebuilt {
typedef typename Qualified<T>::Tconst_reference Tconst_reference;
//! Type to be used as data representation
typedef typename Qualified<T>::Tmutable_value Tmutable_value;
//! Type to pass externally managed pointer to counted reference object
typedef typename Qualified<T>::Tmutable_pointer Tmutable_pointer;
//! Type to be used as element for const version
typedef typename Qualified<T>::Tconst_value Tconst_value;
//! Type of const version of SharedHeap
......@@ -105,6 +140,9 @@ namespace prebuilt {
//! Allocate new heap memory.
SharedHeap(const Tsize& size);
//! Create representation for externally managed memory
SharedHeap(Tpointer* pointer, const Tsize& size);
//! Copy representation to share heap.
SharedHeap(const SharedHeap& sharedheap);
......@@ -133,7 +171,7 @@ namespace prebuilt {
inline
Treference operator[](const Tsubscript& i)
{
#ifdef CONT_INDEXCHECK
#ifdef AFF_INDEXCHECK
int ii=i;
if ((ii>=int(Mheapstruct->Msize)) || (ii<0))
{
......@@ -147,7 +185,7 @@ namespace prebuilt {
inline
Tconst_reference operator[](const Tsubscript& i) const
{
#ifdef CONT_INDEXCHECK
#ifdef AFF_INDEXCHECK
int ii=i;
if ((ii>=int(Mheapstruct->Msize)) || (ii<0))
{
......
......@@ -3,7 +3,7 @@
*
* ----------------------------------------------------------------------------
*
* $Id: sharedheap_def.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $
* $Id: sharedheap_def.h,v 1.3 2002-12-10 19:30:07 forbrig Exp $
* \author Thomas Forbriger
* \since 08/12/2002
*
......@@ -31,7 +31,7 @@
#define AFF_SHAREDHEAP_DEF_H_VERSION \
"AFF_SHAREDHEAP_DEF_H V1.0 "
#define AFF_SHAREDHEAP_DEF_H_CVSID \
"$Id: sharedheap_def.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $"
"$Id: sharedheap_def.h,v 1.3 2002-12-10 19:30:07 forbrig Exp $"
namespace aff {
......@@ -45,47 +45,90 @@ namespace prebuilt {
#endif
#endif
//! instantiate AllocException
AllocException::AllocException(const Tsize& n, const Tsize& size):
Mn(n), Msize(size), Exception("ERROR: memory allocation failed!") { }
//! report AllocException
void AllocException::report() const
{
basereport();
std::cout << " You requested " << n << " memory locations of "
<< size << " Bytes size." << endl;
}
/*----------------------------------------------------------------------*/
//! create counted reference object
template <typename T>
inline
SHeap<T>::SHeap(const Tsize& size)
: Mheap(NULL), Msize(size), Mnref(1)
: Mheap(NULL), Msize(size), Mnref(1), Mextern(false)
{
if (size>0) {
try { Mheap=new T[size]; }
catch (std::bad_alloc) {
throw "SharedHeap::SHeap: allocation error!";
throw AllocException(size, sizeof(T));
}
} else {
Msize=0;
}
}
//! create counted reference object from external memory
template <typename T>
inline
SHeap<T>::SHeap(T* pointer, const Tsize& size)
: Mheap(pointer), Msize(size), Mnref(1), Mextern(true) { }
//! remove counted reference
template <typename T>
inline
SHeap<T>::~SHeap()
{
if ((Mheap!=NULL) && (Msize>0))
if ((Mheap!=NULL) && (Msize>0) && (!Mextern))
{
delete[] Mheap;
}
}
/*----------------------------------------------------------------------*/
//! create representation from nothing
template <typename T>
inline
SharedHeap<T>::SharedHeap()
: Mheapstruct(new Theapstruct(0)) { }
//! create representation for given number of elements
template <typename T>
inline
SharedHeap<T>::SharedHeap(const Tsize& size)
: Mheapstruct(new Theapstruct(size)) { }
/*! \brief create from externally managed memory
*
* In this case we need a static cast to Tmutable_pointer.
* Our concept of const-correctness forces us to use counted references of
* Tmutable_value elements (otherwise we could not share the same counted
* reference with containers of const values). The access operators make
* this save since they will only return values of the correct type (i.e.
* with const qualifier, if T has a const qualifier.
*/
template <typename T>
inline
SharedHeap<T>::SharedHeap(Tpointer* pointer, const Tsize& size);
: Mheapstruct(new Theapstruct(static_cast<Tmutable_pointer>(pointer),
size)) { }
//! create representation from counted reference
template <typename T>
inline
SharedHeap<T>::SharedHeap(Theapstruct* heapstruct)
: Mheapstruct(heapstruct)
{ ++(Mheapstruct->Mnref); }
//! create representation from another representation
template <typename T>
inline
SharedHeap<T>::SharedHeap(const SharedHeap<T>& sharedheap)
......@@ -101,6 +144,7 @@ namespace prebuilt {
{ ++(Mheapstruc->Mnref); }
*/
//! delete representation
template <typename T>
inline
SharedHeap<T>::~SharedHeap()
......@@ -111,6 +155,7 @@ namespace prebuilt {
}
}
//! copy representation by exchanging counted reference
template <typename T>
inline
SharedHeap<T>::SharedHeap&
......@@ -128,6 +173,7 @@ namespace prebuilt {
return(*this);
}
//! return pointer to memory location (why not defined in class declaration?)
template <typename T>
inline
SharedHeap<T>::Tpointer
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment