diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-11-27 08:11:02 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-11-27 08:11:02 +0000 |
commit | 4581dae9ea6d21da0a584aad9f1143343bb7c32e (patch) | |
tree | 4758a696a38343ffa8cc203621e7617d0cec9bfa /include/llvm/ADT/InMemoryStruct.h | |
parent | 10a049e6cf50eb9a1dddae49dc21513cfeddcb47 (diff) | |
download | external_llvm-4581dae9ea6d21da0a584aad9f1143343bb7c32e.zip external_llvm-4581dae9ea6d21da0a584aad9f1143343bb7c32e.tar.gz external_llvm-4581dae9ea6d21da0a584aad9f1143343bb7c32e.tar.bz2 |
ADT/InMemoryStruct: Add an experimental helper class intended for use in
situations where on the common path an API can return a pointer to some direct
memory, but which on an exceptional path may need to return a pointer to a
temporary struct.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120201 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/ADT/InMemoryStruct.h')
-rw-r--r-- | include/llvm/ADT/InMemoryStruct.h | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/include/llvm/ADT/InMemoryStruct.h b/include/llvm/ADT/InMemoryStruct.h new file mode 100644 index 0000000..a560845 --- /dev/null +++ b/include/llvm/ADT/InMemoryStruct.h @@ -0,0 +1,77 @@ +//===- InMemoryStruct.h - Indirect Struct Access Smart Pointer --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_INMEMORYSTRUCT_H +#define LLVM_ADT_INMEMORYSTRUCT_H + +#include <cassert> + +namespace llvm { + +/// \brief Helper object for abstracting access to an in-memory structure which +/// may require some kind of temporary storage. +/// +/// This class is designed to be used for accessing file data structures which +/// in the common case can be accessed from a direct pointer to a memory mapped +/// object, but which in some cases may require indirect access to a temporary +/// structure (which, for example, may have undergone endianness translation). +template<typename T> +class InMemoryStruct { + typedef T value_type; + typedef value_type &reference; + typedef value_type *pointer; + typedef const value_type &const_reference; + typedef const value_type *const_pointer; + + /// \brief The smart pointer target. + value_type *Target; + + /// \brief A temporary object which can be used as a target of the smart + /// pointer. + value_type Contents; + +private: + +public: + InMemoryStruct() : Target(0) {} + InMemoryStruct(reference Value) : Target(&Contents), Contents(Value) {} + InMemoryStruct(pointer Value) : Target(Value) {} + InMemoryStruct(const InMemoryStruct<T> &Value) { *this = Value; } + + void operator=(const InMemoryStruct<T> &Value) { + if (Value.Target != &Value.Contents) { + Target = Value.Target; + } else { + Target = &Contents; + Contents = Value.Contents; + } + } + + const_reference operator*() const { + assert(Target && "Cannot dereference null pointer"); + return *Target; + } + reference operator*() { + assert(Target && "Cannot dereference null pointer"); + return *Target; + } + + const_pointer operator->() const { + return Target; + } + pointer operator->() { + return Target; + } + + operator bool() const { return Target != 0; } +}; + +} + +#endif |