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: 2 June 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
30 Variant(void) : data(NULL) { }
32 Variant(const Variant& other) {
33 if ( other.data != NULL )
43 // NOTE: This code takes care of self-assignment.
44 // DO NOT CHANGE THE ORDER of the statements.
45 Variant& operator= (const Variant& rhs) {
46 if ( rhs.data != NULL )
54 // This member template constructor allows you to
55 // instance a variant_t object with a value of any type.
58 : data(new Impl<T>(v))
63 // This generic conversion operator let you retrieve
64 // the value held. To avoid template specialization conflicts,
65 // it returns an instance of type T, which will be a COPY
66 // of the value contained.
69 return CastFromBase<T>(data)->data;
72 // This forms returns a REFERENCE and not a COPY, which
73 // will be significant in some cases.
75 const T& get(void) const {
76 return CastFromBase<T>(data)->data;
80 bool is_type(void) const {
81 return typeid(*data)==typeid(Impl<T>);
85 bool is_type(T v) const {
86 return typeid(*data)==typeid(v);
92 ImplBase() : refs(0) { }
93 virtual ~ImplBase(void) { }
95 void AddRef(void) { ++refs; }
98 if ( refs == 0 ) delete this;
105 struct Impl : ImplBase {
106 Impl(T v) : data(v) { }
111 // The following method is static because it doesn't
112 // operate on variant_t instances.
114 static Impl<T>* CastFromBase(ImplBase* v) {
115 // This upcast will fail if T is other than the T used
116 // with the constructor of variant_t.
117 Impl<T>* p = dynamic_cast< Impl<T>* > (v);
119 throw std::invalid_argument( typeid(T).name() + std::string(" is not a valid type") );
126 } // namespace BamTools
128 #endif // BAMTOOLS_VARIANT_H