1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-2011,
4 //  Sony Pictures Imageworks Inc. and
5 //  Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
12 // *       Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // *       Redistributions in binary form must reproduce the above
15 // copyright notice, this list of conditions and the following disclaimer
16 // in the documentation and/or other materials provided with the
17 // distribution.
18 // *       Neither the name of Industrial Light & Magic nor the names of
19 // its contributors may be used to endorse or promote products derived
20 // from this software without specific prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 //
34 //-*****************************************************************************
35 
36 #ifndef Alembic_Util_Dimensions_h
37 #define Alembic_Util_Dimensions_h
38 
39 #include <Alembic/Util/Foundation.h>
40 #include <Alembic/Util/PlainOldDataType.h>
41 
42 namespace Alembic {
43 namespace Util {
44 namespace ALEMBIC_VERSION_NS {
45 
46 //-*****************************************************************************
47 template <class T>
48 class BaseDimensions
49 {
50 private:
51     typedef std::vector<T> SizeVec;
52     SizeVec m_vector;
53 
54 public:
55     // Default is for a rank-0 dimension.
BaseDimensions()56     BaseDimensions()
57       : m_vector()
58     {}
59 
60     // When you specify a single thing, you're specifying a rank-1
61     // dimension of a certain size.
BaseDimensions(const T & t)62     explicit BaseDimensions( const T& t )
63       : m_vector( 1, t )
64     {}
65 
BaseDimensions(const BaseDimensions & copy)66     BaseDimensions( const BaseDimensions &copy )
67       : m_vector( copy.m_vector )
68     {}
69 
70     template <class Y>
BaseDimensions(const BaseDimensions<Y> & copy)71     BaseDimensions( const BaseDimensions<Y> &copy )
72     {
73         m_vector.resize( copy.rank() );
74         for ( size_t i = 0; i < copy.rank(); ++i )
75         {
76             Y val = copy[i];
77             m_vector[i] = static_cast<T>( val );
78         }
79     }
80 
81     BaseDimensions& operator=( const BaseDimensions &copy )
82     {
83         m_vector = copy.m_vector;
84         return *this;
85     }
86 
87     template <class Y>
88     BaseDimensions& operator=( const BaseDimensions<Y> &copy )
89     {
90         m_vector.resize( copy.rank() );
91         for ( size_t i = 0; i < copy.rank(); ++i )
92         {
93             Y val = copy[i];
94             m_vector[i] = static_cast<T>( val );
95         }
96         return *this;
97     }
98 
rank()99     size_t rank() const { return m_vector.size(); }
setRank(size_t r)100     void setRank( size_t r )
101     {
102         size_t oldSize = m_vector.size();
103         m_vector.resize( r );
104         for ( size_t s = oldSize; s < r; ++s )
105         {
106             m_vector[s] = ( T )0;
107         }
108     }
109 
110     T &operator[]( size_t i )
111     { return m_vector[i]; }
112 
113     const T &operator[]( size_t i ) const
114     { return m_vector[i]; }
115 
rootPtr()116     T *rootPtr() { return ( T * )( &( m_vector.front() ) ); }
rootPtr()117     const T *rootPtr() const
118     { return ( const T * )( &( m_vector.front() ) ); }
119 
numPoints()120     size_t numPoints() const
121     {
122         if ( m_vector.size() == 0 ) { return 0; }
123         else
124         {
125             size_t npoints = 1;
126             for ( size_t i = 0 ; i < m_vector.size() ; i++ )
127             {
128                 npoints *= (size_t)m_vector[i];
129             }
130             return npoints;
131         }
132     }
133 };
134 
135 //-*****************************************************************************
136 template <class T, class Y>
137 bool operator==( const BaseDimensions<T> &a, const BaseDimensions<Y> &b )
138 {
139     size_t aRank = a.rank();
140     size_t bRank = b.rank();
141     if ( aRank != bRank ) { return false; }
142 
143     if ( sizeof( Y ) > sizeof( T ) )
144     {
145         for ( size_t d = 0; d < aRank; ++d )
146         {
147             if ( static_cast<Y>( a[d] ) !=
148                  static_cast<Y>( b[d] ) ) { return false; }
149         }
150     }
151     else
152     {
153         for ( size_t d = 0; d < aRank; ++d )
154         {
155             if ( static_cast<T>( a[d] ) !=
156                  static_cast<T>( b[d] ) ) { return false; }
157         }
158     }
159 
160     return true;
161 }
162 
163 //-*****************************************************************************
164 template <class T, class Y>
165 inline bool operator!=( const BaseDimensions<T> &a,
166                         const BaseDimensions<Y> &b )
167 {
168     return !( a == b );
169 }
170 
171 //-*****************************************************************************
172 template <class T>
173 std::ostream &operator<<( std::ostream &ostr, const BaseDimensions<T> &a )
174 {
175     ostr << "{";
176     for ( size_t i = 0; i < a.rank(); ++i )
177     {
178         ostr << a[i];
179         if ( i != a.rank()-1 )
180         {
181             ostr << ", ";
182         }
183     }
184     ostr << "}";
185     return ostr;
186 }
187 
188 //-*****************************************************************************
189 typedef BaseDimensions<Alembic::Util::uint64_t> Dimensions;
190 
191 } // End namespace ALEMBIC_VERSION_NS
192 
193 using namespace ALEMBIC_VERSION_NS;
194 
195 } // End namespace Util
196 } // End namespace Alembic
197 
198 #endif
199