Cortex  10.0.0-a4
TypedDataInternals.h
1 //
3 // Copyright (c) 2012, Image Engine Design Inc. All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // * Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // * Neither the name of Image Engine Design nor the names of any
17 // other contributors to this software may be used to endorse or
18 // promote products derived from this software without specific prior
19 // written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
34 
35 #ifndef IECORE_TYPEDDATAINTERNALS_H
36 #define IECORE_TYPEDDATAINTERNALS_H
37 
38 #include "IECore/MurmurHash.h"
39 
40 namespace IECore
41 {
42 
43 template<class T>
44 class SimpleDataHolder
45 {
46 
47  public :
48 
49  SimpleDataHolder()
50  : m_data()
51  {
52  }
53 
54  SimpleDataHolder( const T &data )
55  : m_data( data )
56  {
57  }
58 
59  const T &readable() const
60  {
61  return m_data;
62  }
63 
64  T &writable()
65  {
66  return m_data;
67  }
68 
69  bool operator == ( const SimpleDataHolder<T> &other ) const
70  {
71  return m_data == other.m_data;
72  }
73 
74  void hash( MurmurHash &h ) const
75  {
76  h.append( readable() );
77  }
78 
79  private :
80 
81  T m_data;
82 
83 };
84 
85 template<class T>
86 class SharedDataHolder
87 {
88 
89  public :
90 
91  SharedDataHolder()
92  : m_data( new Shareable )
93  {
94  }
95 
96  SharedDataHolder( const T &data )
97  : m_data( new Shareable( data ) )
98  {
99  }
100 
101  const T &readable() const
102  {
103  assert( m_data );
104  return m_data->data;
105  }
106 
107  T &writable()
108  {
109  assert( m_data );
110  if( m_data->refCount() > 1 )
111  {
112  // duplicate the data
113  m_data = new Shareable( m_data->data );
114  }
115  m_data->hashValid = false;
116  return m_data->data;
117  }
118 
119  bool operator == ( const SharedDataHolder<T> &other ) const
120  {
121  if( m_data==other.m_data )
122  {
123  // comparing the pointers is quick and that's good
124  return true;
125  }
126  // pointers ain't the same - do a potentially slow comparison
127  return readable()==other.readable();
128  }
129 
130  // The method called by the TypedData class when it wants to
131  // append the hash for the internal data into h. This is recomputed
132  // lazily only after writable() has been called. Rather than modify this
133  // function, instead specialise the protected hash() method if the underlying
134  // datatype has special needs.
135  void hash( MurmurHash &h ) const
136  {
137  if( !m_data->hashValid )
138  {
139  m_data->hash = hash();
140  m_data->hashValid = true;
141  }
142  h.append( m_data->hash );
143  }
144 
145  protected :
146 
147  MurmurHash hash() const
148  {
149  MurmurHash result;
150  result.append( &(readable()[0]), readable().size() );
151  return result;
152  }
153 
154  private :
155 
156  class Shareable : public RefCounted
157  {
158  public :
159 
160  Shareable() : data(), hashValid( false ) {}
161  Shareable( const T &initData ) : data( initData ), hashValid( false ) {}
162 
163  T data;
164  MurmurHash hash;
165  volatile bool hashValid;
166 
167  };
168 
169  IE_CORE_DECLAREPTR( Shareable )
170  ShareablePtr m_data;
171 
172 };
173 
174 template <class T>
175 class TypedDataTraits
176 {
177  public:
178  typedef void BaseType;
179  // DataHolder /must/ be specialised to something other than void
180  // using IECORE_DECLARE_TYPEDDATA. It is left void here so that
181  // you must include the appropriate *TypedData.h header - otherwise
182  // you might just include TypedData.h, missing a specialisation which
183  // then causes sizeof( TypedData<T> ) to be incorrect.
184  typedef void DataHolder;
185 };
186 
187 } // namespace IECore
188 
189 #endif // IECORE_TYPEDDATAINTERNALS_H
This namespace contains all components of the core library.
Definition: AddSmoothSkinningInfluencesOp.h:43