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)
39 if(data != NULL) data->Release();
42 // NOTE: This code takes care of self-assignment.
43 // DO NOT CHANGE THE ORDER of the statements.
44 Variant& operator=(const Variant& rhs) {
53 // This member template constructor allows you to
54 // instance a variant_t object with a value of any type.
57 : data(new Impl<T>(v))
62 // This generic conversion operator let you retrieve
63 // the value held. To avoid template specialization conflicts,
64 // it returns an instance of type T, which will be a COPY
65 // of the value contained.
68 return CastFromBase<T>(data)->data;
71 // This forms returns a REFERENCE and not a COPY, which
72 // will be significant in some cases.
74 const T& get(void) const {
75 return CastFromBase<T>(data)->data;
79 bool is_type(void) const {
80 return typeid(*data)==typeid(Impl<T>);
84 bool is_type(T v) const {
85 return typeid(*data)==typeid(v);
91 ImplBase() : refs(0) {}
92 virtual ~ImplBase() {}
94 void AddRef(void) { refs ++; }
97 if(refs == 0) delete this;
104 struct Impl : ImplBase {
105 Impl(T v) : data (v) { }
110 // The following method is static because it doesn't
111 // operate on variant_t instances.
113 static Impl<T>* CastFromBase(ImplBase* v) {
114 // This upcast will fail if T is other than the T used
115 // with the constructor of variant_t.
116 Impl<T>* p = dynamic_cast<Impl<T>*> (v);
118 throw std::invalid_argument(typeid(T).name()+std::string(" is not a valid type"));
125 } // namespace BamTools
127 #endif // BAMTOOLS_VARIANT_H