C++ Library containing a lot of needful things: Stack Trace, Command Line Parser, Resource Handling, Configuration Files, Unix Command Execution, Directories, Regular Expressions, Tokenizer, Function Trace, Standard Extensions.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

143 lines
4.8 KiB

#ifndef __MRW_AUTO_HPP__
#define __MRW_AUTO_HPP__
#include <sys/types.h> // size_t
#include <sys/mman.h> // PROT_READ, MAP_SHARED
#include <bfd.h> // bfd*
namespace mrw {
/** @defgroup AutoTools Classes for Automated Resource Handling
For pointers that have been allocated with @c new, you can use
std::auto_ptr to automatically free them when you leave the
context. Unfortunately there is no such thing for @c malloc
(except @c malloca that only works for a subset of problems: if
you and not a system call allocates memory), @c open and so on.
These classes can take over the resource ownership.
*/
//@{
/** @brief Automatically closes a file when destructed.
@pre #include <mrw/auto.hpp>
AutoFile works exactly like std::auto_ptr, but not for files
instead of pointers. Whenever the context of AutoFile is left,
the opened file is close. This way, resources are freed even in
case of exceptions.
*/
class AutoFile {
public:
/// @brief Construct from an opened file.
/// @note Don't close @c fd
explicit AutoFile(int fd = -1) throw(): _fd(fd) {}
/// @brief Takeover ownership from another AutoFile.
AutoFile(AutoFile& o) throw(): _fd(o.release()) {}
/// @brief Closes file if open.
~AutoFile() throw() {reset();}
/// @brief Assign new file descriptor.
/// The old file of @c this is closed if open.
AutoFile& operator=(int fd) throw() {return reset(fd);}
/// @brief Takeover ownership from another AutoFile.
/// The old file of @c this is closed if open.
AutoFile& operator=(AutoFile& other) throw() {
return reset(other.release());
}
/// @brief get the file descriptor @return file descriptor
operator const int() const throw() {
return _fd;
}
/// @brief Give away ownership of the file. @return old file descriptor
int release() throw() {
int ret(_fd); _fd=-1;
return ret;
}
/// @brief assign a new file descriptor
/** The old file of @c this is closed if open. */
AutoFile& reset(int = -1) throw();
private:
int _fd; ///< the file descriptor
};
/** @brief Automatically call @c munmap for mmaped files on destruction.
@pre #include <mrw/auto.hpp>
It's the same as std::auto_ptr, but for @c mmap instead of @c
new. When the context of @c AutoMapper is left, @c munmap is
called.
*/
class AutoMapper {
public:
AutoMapper(void* cont = 0, size_t sz = 0) throw():
_cont(cont), _sz(sz) {}
AutoMapper(int, size_t=0, void* = 0,
int = PROT_READ, int = MAP_SHARED, off_t = 0) throw();
~AutoMapper() throw();
operator const void*() const throw() {return _cont;}
AutoMapper& set(void* cont, size_t sz) throw() {
_cont=cont; _sz=sz;
return *this;
}
void* release() throw() {
void* ret(_cont); _cont=0; _sz=0;
return ret;
}
const void* last() const throw() {
return _cont && _sz ? (void*)((size_t)_cont+_sz-1) : 0;
}
private:
void* _cont;
size_t _sz;
};
/** @brief Automatically call @c bfd_close for @c bfd*.
@pre #include <mrw/auto.hpp>
It acts like a @c std::auto_ptr, but for @c bfd*, that means it
calls @c bfd_close whenever the context is left.
*/
class AutoBfd {
public:
AutoBfd(bfd* p=0) throw(): _bfd(p) {}
~AutoBfd() throw() {if (_bfd) bfd_close(_bfd);}
AutoBfd& operator=(bfd* p) throw() {
release(); _bfd=p; return *this;
}
AutoBfd& operator=(AutoBfd& o) throw() {
release(); _bfd=o.release(); return *this;
}
operator bfd*() throw() {return _bfd;}
bfd* operator->() throw() {return _bfd;}
bfd* release() throw() {bfd* res(_bfd); _bfd = 0; return res;}
private:
bfd* _bfd;
};
/** @brief Automatically calls @c free for @c malloc allocated memory.
@pre #include <mrw/auto.hpp>
It works like a @c std::auto_ptr, but for memory that was
allocated with @c malloc, not @c new. Memory is freed, whenever
the context od @c AutoFree is left.
*/
template <class T> class AutoFree {
public:
AutoFree(T* p=0) throw(): _p(p) {}
AutoFree(AutoFree& o) throw(): _p(o.release()) {}
~AutoFree() throw() {if (_p) free(_p);}
AutoFree& operator=(T* p) throw() {
release(); _p=p; return *this;
}
AutoFree& operator=(AutoFree& o) throw() {
release(); _p=o.release(); return *this;
}
operator T*() {return _p;}
operator T**() {return &_p;}
operator bool() {return _p;}
T* release() throw() {T* r(_p); _p=0; return r;}
private:
T* _p;
};
//@}
}
#endif