pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_Variable.h
00001 /*
00002  -------------------------------------------------------------------------------
00003  This file is part of the Plink, Plonk, Plank libraries
00004   by Martin Robinson
00005  
00006  http://code.google.com/p/pl-nk/
00007  
00008  Copyright University of the West of England, Bristol 2011-14
00009  All rights reserved.
00010  
00011  Redistribution and use in source and binary forms, with or without
00012  modification, are permitted provided that the following conditions are met:
00013  
00014  * Redistributions of source code must retain the above copyright
00015    notice, this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright
00017    notice, this list of conditions and the following disclaimer in the
00018    documentation and/or other materials provided with the distribution.
00019  * Neither the name of University of the West of England, Bristol nor 
00020    the names of its contributors may be used to endorse or promote products
00021    derived from this software without specific prior written permission.
00022  
00023  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026  DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 
00027  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00028  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00029  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00030  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00032  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00033  
00034  This software makes use of third party libraries. For more information see:
00035  doc/license.txt included in the distribution.
00036  -------------------------------------------------------------------------------
00037  */
00038 
00039 #ifndef PLONK_VARIABLE_H
00040 #define PLONK_VARIABLE_H
00041 
00042 #include "plonk_VariableForwardDeclarations.h"
00043 #include "../plonk_DynamicContainer.h"
00044 
00045 #include "../../core/plonk_SmartPointerContainer.h"
00046 #include "../../core/plonk_WeakPointerContainer.h"
00047 #include "../../core/plonk_SenderContainer.h"
00048 
00049 #include "../../maths/plonk_InlineUnaryOps.h"
00050 #include "../../maths/plonk_InlineBinaryOps.h"
00051 #include "../../maths/plonk_InlineMiscOps.h"
00052 
00053 #include "../../random/plonk_RNG.h"
00054 #include "../plonk_Text.h"
00055 
00066 template<class Type>
00067 class Variable : public SenderContainer< VariableInternalBase<Type> >
00068 {
00069 public:
00070     typedef VariableInternalBase<Type>      Internal;
00071     typedef VariableInternal<Type>          VariableInternalType;
00072     typedef SenderContainer<Internal>       Base;
00073     typedef ReceiverInternal<Variable>      Receiver;
00074     typedef Variable                        Sender;
00075     typedef WeakPointerContainer<Variable>  Weak;
00076     typedef UnitBase<Type>                  UnitType;
00077 
00078     typedef typename BinaryOpFunctionsHelper<Type>::BinaryOpFunctionsType BinaryOpFunctionsType;
00079     typedef typename UnaryOpFunctionsHelper<Type>::UnaryOpFunctionsType UnaryOpFunctionsType;
00080 
00081     typedef PatternVariableInternal<Type>   PatternVariableInternalType;
00082     typedef NumericalArray<Variable>        PatternType;
00083     
00085     inline Variable() throw()
00086     :   Base (new VariableInternalType (Type()))
00087     {
00088     }
00089     
00091     explicit Variable (Internal* internal) throw()
00092     :   Base (internal)
00093     {
00094     }   
00095     
00098     inline Variable (Variable const& copy) throw()
00099     :   Base (static_cast<Base const&> (copy))
00100     {
00101     }
00102     
00103     Variable (Dynamic const& other) throw()
00104     :   Base (other.as<Variable>().getInternal())
00105     {
00106     }    
00107     
00109     Variable& operator= (Variable const& other) throw()
00110         {
00111                 if (this != &other)
00112             this->setInternal (other.getInternal());
00113         
00114         return *this;
00115         }
00116     
00120     static Variable fromWeak (Weak const& weak) throw()
00121     {
00122         return weak.fromWeak();
00123     }
00124             
00125     static const Variable& getNull() throw()
00126         {
00127                 static Variable null;
00128                 return null;
00129         }                       
00130     
00132     inline Variable (Type const& initValue) throw()
00133     :   Base (new VariableInternalType (initValue))
00134     {
00135     }
00136     
00138     Variable (PatternType const& pat) throw()
00139     :   Base (new PatternVariableInternalType (pat))
00140     {
00141     }
00142     
00144     template<class OtherType>
00145     Variable (NumericalArray< Variable<OtherType> > const& pat) throw()
00146     :   Base (new TypeVariableInternal<Type,OtherType> (Variable<OtherType> (static_cast< VariableInternalBase<OtherType>* > (new PatternVariableInternal<OtherType> (pat)))))
00147     {
00148         // what a nasty expression!
00149     }
00150     
00152     template<class OtherType>
00153     inline Variable (OtherType const& other) throw()
00154     :   Base (new TypeVariableInternal<Type,OtherType> (other))
00155     {
00156     }
00157     
00159     template<class ValueType>
00160     Variable& operator= (ValueType const& newValue) throw()
00161     {
00162         this->setValue (newValue);
00163         return *this;
00164     }
00165     
00167     inline const Type getValue() const throw()
00168     {
00169         return this->getInternal()->getValue();
00170     }
00171     
00173     inline Type* getValuePtr() throw()
00174     {
00175         return this->getInternal()->getValuePtr();
00176     }
00177     
00179     inline operator Type () const throw()
00180     {
00181         return this->getInternal()->getValue();
00182     }
00183     
00187     inline const Type nextValue() throw()
00188     {
00189         return this->getInternal()->nextValue();
00190     }
00191     
00193     inline void setValue (Type const& newValue) throw()
00194     {
00195         this->getInternal()->setValue (newValue);
00196     }    
00197     
00198     inline void swapValues (Type& other) throw()
00199     {
00200         this->getInternal()->swapValues (other);
00201     }
00202                     
00204     template<PLONK_BINARYOPFUNCTION(Type, op)>
00205     Variable binary (Variable const& rightOperand) const throw()
00206     {
00207         Internal* internal = new BinaryOpVariableInternal<Type,op> (*this, rightOperand);
00208         return Variable (internal);
00209     }
00210     
00212     template<PLONK_UNARYOPFUNCTION(Type, op)>
00213     Variable unary() const throw()
00214     {
00215         Internal* internal = new UnaryOpVariableInternal<Type,op> (*this);
00216         return Variable (internal);
00217     }
00218     
00219     PLONK_BINARYOPS(Variable)
00220     PLONK_UNARYOPS(Variable)
00221     
00222     Variable linlin (Variable const& inLow, Variable const& inHigh, Variable const& outLow, Variable const& outHigh) const throw()
00223     {
00224         return plonk::linlin (*this, inLow, inHigh, outLow, outHigh);
00225     }
00226     
00227     Variable linexp (Variable const& inLow, Variable const& inHigh, Variable const& outLow, Variable const& outHigh) const throw()
00228     {
00229         return plonk::linexp (*this, inLow, inHigh, outLow, outHigh);
00230     }
00231     
00232     Variable explin (Variable const& inLow, Variable const& inHigh, Variable const& outLow, Variable const& outHigh) const throw()
00233     {
00234         return plonk::explin (*this, inLow, inHigh, outLow, outHigh);
00235     }
00236     
00237     Variable linwelch (Variable const& inLow, Variable const& inHigh, Variable const& outLow, Variable const& outHigh) const throw()
00238     {
00239         return plonk::linwelch (*this, inLow, inHigh, outLow, outHigh);
00240     }
00241 
00242     
00243     typedef ShapeVariableInternal<Type>     ShapeVariableInternalType;
00244     typedef IntVariable                     StepsVariable;
00245     typedef Variable<Shape::ShapeType>      ShapeTypeVariable;
00246     typedef FloatVariable                   CurveVariable;
00247     
00249     Variable shape (StepsVariable const& numSteps) const throw()
00250     {
00251         Internal* internal = new ShapeVariableInternalType (*this, numSteps, Shape::Linear, 0.f);
00252         return Variable (internal);
00253     }
00254     
00256     Variable shape (StepsVariable const& numSteps,
00257                     ShapeTypeVariable const& shapeType) const throw()
00258     {
00259         Internal* internal = new ShapeVariableInternalType (*this, numSteps, shapeType, 0.f);
00260         return Variable (internal);
00261     }
00262     
00264     Variable shape (StepsVariable const& numSteps,
00265                     ShapeTypeVariable const& shapeType,
00266                     CurveVariable const& curve) const throw()
00267     {
00268         Internal* internal = new ShapeVariableInternalType (*this, numSteps, shapeType, curve);
00269         return Variable (internal);
00270     }
00271     
00272     Variable selectMin (Variable const& other) const throw()
00273     {
00274         return (this->getValue() > other.getValue()) ? other : *this;
00275     }    
00276     
00277     Variable selectMax (Variable const& other) const throw()
00278     {
00279         return (this->getValue() < other.getValue()) ? other : *this;
00280     }
00281             
00282     int getTypeCode() const throw()
00283     {
00284         return TypeUtility<Variable>::getTypeCode();
00285     }
00286     
00287     int getValueTypeCode() const throw()
00288     {
00289         return TypeUtility<Type>::getTypeCode();
00290     }        
00291     
00292     inline UnitType ar() const throw()
00293     {
00294         return UnitType (*this).ar();
00295     }
00296     
00297     inline UnitType kr() const throw()
00298     {
00299         return UnitType (*this).kr();
00300     }
00301     
00302     inline UnitType ar (const Interp::TypeCode interpType) const throw()
00303     {
00304         return UnitType (*this).ar (interpType);
00305     }
00306     
00307     inline UnitType kr (const Interp::TypeCode interpType) const throw()
00308     {
00309         return UnitType (*this).kr (interpType);
00310     }
00311 };
00312 
00313 PLONK_BINARYOPGLOBALS_TEMPLATE(Variable,Type); // declares global functions with the same name as the binary operators
00314 PLONK_UNARYOPGLOBALS_TEMPLATE(Variable,Type);  // declares global functions with the same name as the unary operators
00315 
00316 template<class Type>
00317 inline UnitBase<Type> ar (Variable<Type> v) throw()
00318 {
00319     return UnitBase<Type> (v).ar();
00320 }
00321 
00322 template<class Type>
00323 inline UnitBase<Type> kr (Variable<Type> v) throw()
00324 {
00325     return UnitBase<Type> (v).kr();
00326 }
00327 
00328 #if !PLONK_ANDROID
00329 template<class Type>
00330 std::istream& operator>> (std::istream &inputStream, Variable<Type>& variable)
00331 {
00332     Type value;
00333     inputStream >> value;
00334     
00335     variable = Variable<Type> (value);
00336     
00337     return inputStream;
00338 }
00339 
00340 template<class Type>
00341 std::ostream& operator<< (std::ostream &outputStream, Variable<Type> const& variable)
00342 {
00343     outputStream << variable.getValue();
00344     return outputStream;
00345 }
00346 #endif
00347     
00348 //BINARYOPGLOBALS(Variable) // declares global functions with the same name as the binary operators
00349 //UNARYOPGLOBALS(Variable)  // declares global functions with the same name as the unary operators
00350 
00356 template<class Type>
00357 class Variable<Type&> : public SmartPointerContainer< VariableInternal<Type&> >
00358 {
00359 public:
00360     typedef VariableInternal<Type&>         Internal;
00361     typedef SmartPointerContainer<Internal> Base;
00362     
00363     Variable()
00364     :   Base (new Internal (Type()))
00365     {
00366     }
00367     
00368     Variable (Variable const& copy) throw()
00369         :       Base (static_cast<Base const&> (copy))
00370         {
00371         }        
00372     
00373     Variable (Type& initValue) throw()
00374     :   Base (new Internal (initValue))
00375     {
00376     }
00377     
00378     template<class ValueType>
00379     Variable (ValueType const& initValue) throw()
00380     :   Base (new Internal (initValue))
00381     {
00382     }    
00383             
00384     template<class ValueType>
00385     inline Variable& operator= (ValueType const& newValue) throw()
00386     {
00387         Type temp (newValue);
00388         this->swapValues (temp);
00389         return *this;
00390     }    
00391     
00392     inline Variable& operator= (Variable const& other) throw()
00393     {
00394         Variable temp (other.getValue());
00395         this->swapValues (temp);
00396         return *this;
00397     }    
00398 
00399     inline Type& getValue() throw()
00400     {
00401         return this->getInternal()->getValue();
00402     }
00403     
00404     inline const Type& getValue() const throw()
00405     {
00406         return this->getInternal()->getValue();
00407     }
00408     
00409     inline operator Type& () throw()
00410     {
00411         return this->getInternal()->getValue();
00412     }
00413     
00414     template<class ValueType>
00415     inline operator ValueType() throw()
00416     {
00417         return ValueType (this->getInternal()->getValue());
00418     }
00419     
00420     template<class ValueType>
00421     inline void setValue (ValueType const& newValue) throw()
00422     {
00423         this->getInternal()->setValue (newValue);
00424     }    
00425     
00426     inline void swapValues (Type& other) throw()
00427     {
00428         this->getInternal()->swapValues (other);
00429     }
00430     
00431     inline void swapValues (Variable& other) throw()
00432     {
00433         this->getInternal()->swapValues (other.getValue());
00434     }
00435     
00436     inline bool isValueNull() const throw()
00437     {
00438         return this->getInternal()->getValue().isNull();
00439     }
00440 
00441     inline bool isValueNotNull() const throw()
00442     {
00443         return this->getInternal()->getValue().isNotNull();
00444     }
00445     
00446     PLONK_OBJECTARROWOPERATOR(Variable);
00447 };
00448 
00449 
00450 #endif // PLONK_VARIABLE_H
 All Classes Functions Typedefs Enumerations Enumerator Properties