1 // ***************************************************************************
2 // bamtools_variant.h (c) 2010 Derek Barnett, Erik Garrison
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 19 November 2010
7 // ---------------------------------------------------------------------------
8 // Provides a template-based variant type
9 // ---------------------------------------------------------------------------
11 // variant_t - An Improved Variant Type Based on Member Templates
12 // (c) 2000 Fernando Cacciola
13 // Dr. Dobb's (http://www.ddj.com/cpp/184401293)
15 // * Modified to be in BamTools namespace, otherwise code is same. (DB)
16 // ***************************************************************************
18 #ifndef BAMTOOLS_VARIANT_H
19 #define BAMTOOLS_VARIANT_H
21 #include <utils/utils_global.h>
28 class UTILS_EXPORT Variant {
31 Variant(void) : data(NULL) { }
33 Variant(const Variant& other) {
34 if ( other.data != NULL )
44 // NOTE: This code takes care of self-assignment.
45 // DO NOT CHANGE THE ORDER of the statements.
46 Variant& operator= (const Variant& rhs) {
47 if ( rhs.data != NULL )
55 // This member template constructor allows you to
56 // instance a variant_t object with a value of any type.
59 : data(new Impl<T>(v))
64 // This generic conversion operator let you retrieve
65 // the value held. To avoid template specialization conflicts,
66 // it returns an instance of type T, which will be a COPY
67 // of the value contained.
70 return CastFromBase<T>(data)->data;
73 // This forms returns a REFERENCE and not a COPY, which
74 // will be significant in some cases.
76 const T& get(void) const {
77 return CastFromBase<T>(data)->data;
81 bool is_type(void) const {
82 return typeid(*data)==typeid(Impl<T>);
86 bool is_type(T v) const {
87 return typeid(*data)==typeid(v);
93 ImplBase() : refs(0) { }
94 virtual ~ImplBase(void) { }
96 void AddRef(void) { ++refs; }
99 if ( refs == 0 ) delete this;
106 struct Impl : ImplBase {
107 Impl(T v) : data(v) { }
112 // The following method is static because it doesn't
113 // operate on variant_t instances.
115 static Impl<T>* CastFromBase(ImplBase* v) {
116 // This upcast will fail if T is other than the T used
117 // with the constructor of variant_t.
118 Impl<T>* p = dynamic_cast< Impl<T>* > (v);
120 throw std::invalid_argument( typeid(T).name() + std::string(" is not a valid type") );
127 } // namespace BamTools
129 #endif // BAMTOOLS_VARIANT_H