Simbody
3.4 (development)
|
00001 #ifndef SimTK_SimTKCOMMON_VALUE_H_ 00002 #define SimTK_SimTKCOMMON_VALUE_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * Simbody(tm): SimTKcommon * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. * 00011 * * 00012 * Portions copyright (c) 2005-12 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: * 00015 * * 00016 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 00017 * not use this file except in compliance with the License. You may obtain a * 00018 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 00019 * * 00020 * Unless required by applicable law or agreed to in writing, software * 00021 * distributed under the License is distributed on an "AS IS" BASIS, * 00022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00023 * See the License for the specific language governing permissions and * 00024 * limitations under the License. * 00025 * -------------------------------------------------------------------------- */ 00026 00027 #include "SimTKcommon/internal/common.h" 00028 00029 #include "SimTKcommon/internal/String.h" 00030 #include "SimTKcommon/internal/Exception.h" 00031 00032 #include <limits> 00033 #include <typeinfo> 00034 #include <sstream> 00035 00036 namespace SimTK { 00037 00041 class AbstractValue { 00042 public: 00043 AbstractValue() { } 00044 virtual ~AbstractValue() { } 00045 00046 virtual String getTypeName() const = 0; 00047 virtual String getValueAsString() const = 0; 00048 virtual bool isCompatible(const AbstractValue&) const = 0; 00049 virtual void compatibleAssign(const AbstractValue&) = 0; 00050 00051 AbstractValue& operator=(const AbstractValue& v) { compatibleAssign(v); return *this; } 00052 00053 virtual AbstractValue* clone() const = 0; 00054 }; 00055 00056 inline std::ostream& 00057 operator<<(std::ostream& o, const AbstractValue& v) { o << v.getValueAsString(); return o; } 00058 00067 template <class T> class Value : public AbstractValue { 00068 public: 00069 Value() { } // contained value is default-constructed 00070 explicit Value(const T& t) : thing(t) { } 00071 // default copy, destructor 00072 00073 // Define assignment explicitly here to avoid implicitly calling AbstractValue's 00074 // assignment operator. 00075 Value& operator=(const Value& v) { thing = v.thing; return *this; } 00076 00077 Value& operator=(const T& t) { thing=t; return *this; } 00078 operator const T&() const { return thing; } // automatic conversion to T 00079 operator T&() { return thing; } // automatic conversion to T 00080 00081 const T& get() const { return thing; } 00082 00083 // two ways to assign to a new value 00084 void set(const T& t) { thing = t; } 00085 T& upd() { return thing; } 00086 00087 bool isCompatible(const AbstractValue& v) const { return isA(v); } 00088 void compatibleAssign(const AbstractValue& v) { 00089 if (!isA(v)) SimTK_THROW2(Exception::IncompatibleValues,v.getTypeName(),getTypeName()); 00090 *this = downcast(v); 00091 } 00092 String getTypeName() const { return NiceTypeName<T>::name(); } 00093 // TODO: should have some general way to serialize these. 00094 String getValueAsString() const 00095 { return "Value<" + getTypeName() + ">"; } 00096 00097 AbstractValue* clone() const { return new Value(*this); } 00098 SimTK_DOWNCAST(Value,AbstractValue); 00099 protected: 00100 T thing; 00101 }; 00102 00103 00104 00105 } // namespace SimTK 00106 00107 #endif // SimTK_SimTKCOMMON_VALUE_H_