nemo/Mapping.h
Go to the documentation of this file.00001 #ifndef _NEMO_MAPPING_H_ 00002 #define _NEMO_MAPPING_H_ 00003 00004 00005 //#include <boost/smart_ptr/intrusive_ptr.hpp> 00006 #include <boost/bind.hpp> 00007 00008 00009 #include "IntrusiveCounted.h" 00010 #include "IntrusivePtr.h" 00011 #include "detail/nemo-cpp11.h" 00012 #include "detail/nemo-errors.h" 00013 00014 #include <stdexcept> 00015 00016 00017 00018 00019 namespace nemo { 00020 00021 00022 00038 template <class InType, class OutType> 00039 class MappingDefinition : public IntrusiveCounted<MappingDefinition<InType,OutType> >{ 00040 public: 00041 00045 virtual OutType evaluate(InType value) const = 0; 00046 00057 virtual MappingDefinition<OutType,InType>* getInverse() const { 00058 _NEMO_LOGIC_ERROR("Inversion not supported for this mapping type"); 00059 } 00060 00061 virtual ~MappingDefinition(){} 00062 }; 00063 00064 template <class InType, class OutType> 00065 class Mapping; 00066 00067 #ifndef NEMO_PARSED_BY_DOXYGEN 00068 00071 template <class T> 00072 class Identity : public MappingDefinition<T,T> { 00073 public: 00074 static Mapping<T,T> create(){ 00075 return Mapping<T,T>(new Identity<T>()); 00076 } 00077 00078 MappingDefinition<T,T>* getInverse() const { 00079 return new Identity<T>(); 00080 } 00081 00082 T evaluate(T value) const { 00083 return value; 00084 } 00085 }; 00086 #endif 00087 00091 template <class T> 00092 static Mapping<T,T> arg(){ return Identity<T>::create(); } 00093 00094 00095 #ifndef NEMO_PARSED_BY_DOXYGEN 00096 namespace detail { 00101 template <class InType, class Intermediate, class OutType> 00102 class SequentialMapping : public MappingDefinition<InType,OutType> { 00103 public: 00104 OutType evaluate(InType value) const{ 00105 return second->evaluate(first->evaluate(value)); 00106 } 00107 MappingDefinition<OutType,InType>* getInverse() const { 00108 IntrusivePtr<MappingDefinition<Intermediate,InType> > firstInv( first->getInverse() ); 00109 IntrusivePtr<MappingDefinition<OutType,Intermediate> > secondInv( second->getInverse() ); 00110 return new SequentialMapping<OutType,Intermediate,InType>( secondInv, firstInv ); 00111 } 00116 SequentialMapping( 00117 IntrusivePtr<MappingDefinition<InType,Intermediate> > firstP, 00118 IntrusivePtr<MappingDefinition<Intermediate,OutType> > secondP) 00119 : first(firstP), second(secondP) 00120 {} 00121 private: 00122 friend class Mapping<Intermediate,OutType>; 00123 00124 IntrusivePtr<MappingDefinition<InType,Intermediate> > first; 00125 IntrusivePtr<MappingDefinition<Intermediate,OutType> > second; 00126 }; 00127 template <class InType, class Intermediate, class OutType> 00128 class CastMappingDef : public MappingDefinition<InType,OutType> { 00129 public: 00130 00131 OutType evaluate(InType input) const { 00132 return (OutType)(map->evaluate(input)); 00133 } 00134 00135 MappingDefinition<OutType,InType>* getInverse() const { 00136 IntrusivePtr<MappingDefinition<Intermediate,InType> > innerInv( map->getInverse() ); 00137 IntrusivePtr<MappingDefinition<OutType,Intermediate> > castInv( 00138 new CastMappingDef<OutType,OutType,Intermediate>( 00139 IntrusivePtr<MappingDefinition<OutType,OutType> >(new Identity<OutType>()) 00140 ) 00141 ); 00142 return new SequentialMapping<OutType,Intermediate,InType>( castInv, innerInv ); 00143 } 00144 00145 CastMappingDef(IntrusivePtr<MappingDefinition<InType,Intermediate> > mapP) : map(mapP) {} 00146 private: 00147 IntrusivePtr<MappingDefinition<InType,Intermediate> > map; 00148 }; 00149 }// end namespace detail 00150 #endif 00151 00160 template <class InType, class OutType> 00161 class Mapping { 00162 public: 00166 Mapping(MappingDefinition<InType,OutType> *defP) 00167 : def(defP) 00168 { 00169 if(!defP){ 00170 _NEMO_ARGUMENT_ERROR("Received null pointer as MappingDefinition"); 00171 } 00172 } 00173 00177 Mapping() 00178 : def(new ConstMappingDef(OutType())) 00179 {} 00180 00184 Mapping(const OutType &value) 00185 : def(new ConstMappingDef(value)) 00186 {} 00187 00192 Mapping(OutType (*const func)(InType), InType (*const invFunc)(OutType) = NULL) 00193 : def(new CFuncMappingDef<InType,OutType>(func,invFunc)) 00194 { 00195 if(!func){ 00196 _NEMO_ARGUMENT_ERROR("Received null function pointer"); 00197 } 00198 } 00199 00203 template <typename F, typename BoostArgDescription> 00204 Mapping(boost::_bi::bind_t<OutType, F, BoostArgDescription > func) 00205 : def(new BoostBindMappingDef<InType,OutType,F,BoostArgDescription>(func)) 00206 {} 00207 00211 OutType operator()(InType value) const{ 00212 return def->evaluate(value); 00213 } 00214 00218 template <typename OtherInType> 00219 Mapping<OtherInType,OutType> operator()(Mapping<OtherInType,InType> m){ 00220 //return SequentialMapping<InType,OutType,OtherOutType>::create(m->def, this->def); 00221 return Mapping<OtherInType,OutType>(new detail::SequentialMapping<OtherInType,InType,OutType>(m.def, this->def)); 00222 } 00223 00227 inline IntrusivePtr<MappingDefinition<InType,OutType> > getDefinition() const{ 00228 return def; 00229 } 00230 00231 Mapping<OutType,InType> inverse(){ 00232 MappingDefinition<OutType,InType> *invDef = def->getInverse(); 00233 return Mapping<OutType,InType>(invDef); 00234 } 00235 00236 private: 00237 // declare mappings with arbitrary other type-parameters as friend 00238 template <class I, class O> 00239 friend class Mapping; 00240 00241 IntrusivePtr<MappingDefinition<InType,OutType> > def; 00242 00243 #ifndef NEMO_PARSED_BY_DOXYGEN 00244 00247 //template <class InType, class OutType> 00248 class ConstMappingDef : public MappingDefinition<InType,OutType> { 00249 public: 00250 static Mapping<InType,OutType> create(OutType value){ 00251 return Mapping<InType,OutType>(new ConstMappingDef(value)); 00252 } 00253 00254 OutType evaluate(InType) const { 00255 return value; 00256 } 00257 00258 ConstMappingDef(OutType valueP) : value(valueP) {} 00259 private: 00260 OutType value; 00261 }; 00262 00266 template <typename I, typename O> 00267 class CFuncMappingDef : public MappingDefinition<I,O> { 00268 public: 00269 O evaluate(I value) const { 00270 return func(value); 00271 } 00272 00273 MappingDefinition<O,I>* getInverse() const { 00274 if(!inverse){ 00275 _NEMO_LOGIC_ERROR("No inverse function specified for this function pointer"); 00276 } 00277 return new CFuncMappingDef<O,I>(inverse,func); 00278 } 00279 00280 CFuncMappingDef(O (*const funcP)(I), I (*const inverseP)(O)) : func(funcP), inverse(inverseP) {} 00281 private: 00282 O (*const func)(I); 00283 I (*const inverse)(O); 00284 }; 00285 00289 template <typename I, typename O, typename F, typename BoostArgDescription> 00290 class BoostBindMappingDef : public MappingDefinition<I,O> { 00291 public: 00292 O evaluate(I value) const { 00293 return func(value); 00294 } 00295 00296 BoostBindMappingDef(boost::_bi::bind_t<OutType, F, BoostArgDescription> funcP) : func(funcP) {} 00297 private: 00298 boost::_bi::bind_t<O, F, BoostArgDescription > func; 00299 }; 00300 #endif 00301 00302 }; 00303 00309 template <class OutType, typename InType, typename Intermediate> 00310 Mapping<InType,OutType> 00311 reinterpret(const Mapping<InType,Intermediate> &map){ 00312 return Mapping<InType,OutType>(new detail::CastMappingDef<InType,Intermediate,OutType>(map.getDefinition())); 00313 } 00314 00315 00317 template <typename Type> Type leftMultInverse(const Type &) 00318 {_NEMO_LOGIC_ERROR("leftMultInverse not defined for this data type");} 00320 template <typename Type> Type rightMultInverse(const Type &) 00321 {_NEMO_LOGIC_ERROR("rightMultInverse not defined for this data type");} 00323 template <typename Type> Type leftDivideInverse(const Type &) 00324 {_NEMO_LOGIC_ERROR("leftDivideInverse not defined for this data type");} 00326 template <typename Type> Type rightDivideInverse(const Type &) 00327 {_NEMO_LOGIC_ERROR("rightDivideInverse not defined for this data type");} 00329 template <typename Type> Type leftAddInverse(const Type &) 00330 {_NEMO_LOGIC_ERROR("leftAddInverse not defined for this data type");} 00332 template <typename Type> Type rightAddInverse(const Type &) 00333 {_NEMO_LOGIC_ERROR("rightAddInverse not defined for this data type");} 00335 template <typename Type> Type leftSubtractInverse(const Type &) 00336 {_NEMO_LOGIC_ERROR("leftSubtractInverse not defined for this data type");} 00338 template <typename Type> Type rightSubtractInverse(const Type &) 00339 {_NEMO_LOGIC_ERROR("rightSubtractInverse not defined for this data type");} 00340 00341 00342 00343 #ifndef NEMO_PARSED_BY_DOXYGEN 00344 #define _nemo_mapping_binary_operators_(Name, OP) \ 00345 template <class InType, class InnerOutType1, class InnerOutType2, class OutType> \ 00346 class Name##Mapping : public MappingDefinition<InType,OutType> { \ 00347 public: \ 00348 OutType evaluate(InType value) const{ \ 00349 return first->evaluate(value) OP second->evaluate(value); \ 00350 } \ 00351 Name##Mapping( \ 00352 const IntrusivePtr<MappingDefinition<InType,InnerOutType1> > &firstP, \ 00353 const IntrusivePtr<MappingDefinition<InType,InnerOutType2> > &secondP) \ 00354 : first(firstP), second(secondP) {} \ 00355 private: \ 00356 IntrusivePtr<MappingDefinition<InType,InnerOutType1> > first; \ 00357 IntrusivePtr<MappingDefinition<InType,InnerOutType2> > second; \ 00358 }; \ 00359 template <class InType, class InnerOutType1, class InnerOutType2, class OutType> \ 00360 class Name##MappingConst : public MappingDefinition<InType,OutType> { \ 00361 public: \ 00362 OutType evaluate(InType value) const{ \ 00363 return first->evaluate(value) OP constValue; \ 00364 } \ 00365 Name##MappingConst( \ 00366 const IntrusivePtr<MappingDefinition<InType,InnerOutType1> > &firstP, \ 00367 const InnerOutType2 &constValueP) \ 00368 : first(firstP), constValue(constValueP) \ 00369 {} \ 00370 private: \ 00371 IntrusivePtr<MappingDefinition<InType,InnerOutType1> > first; \ 00372 InnerOutType2 constValue; \ 00373 }; \ 00374 template <class InType, class InnerOutType1, class InnerOutType2, class OutType> \ 00375 class Name##ConstMapping : public MappingDefinition<InType,OutType> { \ 00376 public: \ 00377 OutType evaluate(InType value) const{ \ 00378 return constValue OP second->evaluate(value); \ 00379 } \ 00380 MappingDefinition<OutType,InType>* getInverse() const { \ 00381 _NEMO_LOGIC_ERROR("Inversion not supported for 'OP' mapping type"); \ 00382 } \ 00383 Name##ConstMapping( const InnerOutType1 &constValueP, const IntrusivePtr<MappingDefinition<InType,InnerOutType2> > &secondP) \ 00384 : constValue(constValueP), second(secondP) {} \ 00385 private: \ 00386 InnerOutType1 constValue; \ 00387 IntrusivePtr<MappingDefinition<InType,InnerOutType2> > second; \ 00388 }; \ 00389 template <class InType, class InnerOutType1, class InnerOutType2> \ 00390 inline Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))> operator OP (Mapping<InType,InnerOutType1> l, Mapping<InType,InnerOutType2> r){ \ 00391 return Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(new Name##Mapping<InType,InnerOutType1,InnerOutType2,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(l.getDefinition(), r.getDefinition())); \ 00392 } \ 00393 template <class InType, class InnerOutType1, class InnerOutType2> \ 00394 inline Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))> operator OP (Mapping<InType,InnerOutType1> l, const InnerOutType2 &r){ \ 00395 return Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(new Name##MappingConst<InType,InnerOutType1,InnerOutType2,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(l.getDefinition(), r)); \ 00396 } \ 00397 template <class InType, class InnerOutType1, class InnerOutType2> \ 00398 inline Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))> operator OP (const InnerOutType1 &l, Mapping<InType,InnerOutType2> r){ \ 00399 return Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(new Name##ConstMapping<InType,InnerOutType1,InnerOutType2,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(l, r.getDefinition())); \ 00400 } 00401 00402 00403 00404 #define _nemo_mapping_binary_operators_invertible_(Name, OP) \ 00405 template <class InType, class InnerOutType1, class InnerOutType2, class OutType> \ 00406 class Name##Mapping : public MappingDefinition<InType,OutType> { \ 00407 public: \ 00408 OutType evaluate(InType value) const{ \ 00409 return first->evaluate(value) OP second->evaluate(value); \ 00410 } \ 00411 Name##Mapping( \ 00412 const IntrusivePtr<MappingDefinition<InType,InnerOutType1> > &firstP, \ 00413 const IntrusivePtr<MappingDefinition<InType,InnerOutType2> > &secondP) \ 00414 : first(firstP), second(secondP) {} \ 00415 private: \ 00416 IntrusivePtr<MappingDefinition<InType,InnerOutType1> > first; \ 00417 IntrusivePtr<MappingDefinition<InType,InnerOutType2> > second; \ 00418 }; \ 00419 template <class InType, class InnerOutType1, class InnerOutType2, class OutType> \ 00420 class Name##MappingConst : public MappingDefinition<InType,OutType> { \ 00421 public: \ 00422 OutType evaluate(InType value) const{ \ 00423 return first->evaluate(value) OP constValue; \ 00424 } \ 00425 MappingDefinition<OutType,InType>* getInverse() const { \ 00426 IntrusivePtr<MappingDefinition<InnerOutType1,InType> > mapInv(first->getInverse()); \ 00427 IntrusivePtr<MappingDefinition<OutType,InnerOutType1> > innerInv( \ 00428 new detail::CastMappingDef<OutType,_nemo_get_type_(OutType() OP constValue),InnerOutType1>( \ 00429 IntrusivePtr<MappingDefinition<OutType,_nemo_get_type_(OutType() OP constValue)> >( \ 00430 new Name##MappingConst<OutType,OutType,InnerOutType2,_nemo_get_type_(OutType() OP constValue)>( \ 00431 IntrusivePtr<MappingDefinition<OutType,OutType> >(new Identity<OutType>()), \ 00432 right##Name##Inverse<InnerOutType2>( constValue ) \ 00433 ) \ 00434 ) \ 00435 ) \ 00436 ); \ 00437 return new detail::SequentialMapping<OutType,InnerOutType1,InType>(innerInv, mapInv); \ 00438 } \ 00439 Name##MappingConst( \ 00440 const IntrusivePtr<MappingDefinition<InType,InnerOutType1> > &firstP, \ 00441 const InnerOutType2 &constValueP) \ 00442 : first(firstP), constValue(constValueP) \ 00443 {} \ 00444 private: \ 00445 IntrusivePtr<MappingDefinition<InType,InnerOutType1> > first; \ 00446 InnerOutType2 constValue; \ 00447 }; \ 00448 template <class InType, class InnerOutType1, class InnerOutType2, class OutType> \ 00449 class Name##ConstMapping : public MappingDefinition<InType,OutType> { \ 00450 public: \ 00451 OutType evaluate(InType value) const{ \ 00452 return constValue OP second->evaluate(value); \ 00453 } \ 00454 MappingDefinition<OutType,InType>* getInverse() const { \ 00455 IntrusivePtr<MappingDefinition<InnerOutType2,InType> > mapInv(second->getInverse()); \ 00456 IntrusivePtr<MappingDefinition<OutType,InnerOutType2> > innerInv( \ 00457 new detail::CastMappingDef<OutType,_nemo_get_type_(constValue OP OutType()),InnerOutType2>( \ 00458 IntrusivePtr<MappingDefinition<OutType,_nemo_get_type_(constValue OP OutType())> >( \ 00459 new Name##ConstMapping<OutType,InnerOutType1,OutType,_nemo_get_type_(constValue OP OutType())>( \ 00460 left##Name##Inverse<InnerOutType1>( constValue ), \ 00461 IntrusivePtr<MappingDefinition<OutType,OutType> >(new Identity<OutType>()) \ 00462 ) \ 00463 ) \ 00464 ) \ 00465 ); \ 00466 return new detail::SequentialMapping<OutType,InnerOutType2,InType>(innerInv, mapInv); \ 00467 } \ 00468 Name##ConstMapping( const InnerOutType1 &constValueP, const IntrusivePtr<MappingDefinition<InType,InnerOutType2> > &secondP) \ 00469 : constValue(constValueP), second(secondP) {} \ 00470 private: \ 00471 InnerOutType1 constValue; \ 00472 IntrusivePtr<MappingDefinition<InType,InnerOutType2> > second; \ 00473 }; \ 00474 template <class InType, class InnerOutType1, class InnerOutType2> \ 00475 inline Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))> operator OP (Mapping<InType,InnerOutType1> l, Mapping<InType,InnerOutType2> r){ \ 00476 return Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(new Name##Mapping<InType,InnerOutType1,InnerOutType2,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(l.getDefinition(), r.getDefinition())); \ 00477 } \ 00478 template <class InType, class InnerOutType1, class InnerOutType2> \ 00479 inline Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))> operator OP (Mapping<InType,InnerOutType1> l, const InnerOutType2 &r){ \ 00480 return Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(new Name##MappingConst<InType,InnerOutType1,InnerOutType2,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(l.getDefinition(), r)); \ 00481 } \ 00482 template <class InType, class InnerOutType1, class InnerOutType2> \ 00483 inline Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))> operator OP (const InnerOutType1 &l, Mapping<InType,InnerOutType2> r){ \ 00484 return Mapping<InType,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(new Name##ConstMapping<InType,InnerOutType1,InnerOutType2,_nemo_get_type_((InnerOutType1() OP InnerOutType2()))>(l, r.getDefinition())); \ 00485 } 00486 #endif 00487 00488 #ifndef NEMO_PARSED_BY_DOXYGEN 00489 _nemo_mapping_binary_operators_invertible_(Add, +) 00490 _nemo_mapping_binary_operators_invertible_(Subtract, -) 00491 _nemo_mapping_binary_operators_invertible_(Mult, *) 00492 _nemo_mapping_binary_operators_invertible_(Divide, /) 00493 00494 _nemo_mapping_binary_operators_(Modulo, %) 00495 _nemo_mapping_binary_operators_(BitAnd, &) 00496 _nemo_mapping_binary_operators_(BitOr, |) 00497 _nemo_mapping_binary_operators_(BitXor, ^) 00498 _nemo_mapping_binary_operators_(LeftShift, <<) 00499 _nemo_mapping_binary_operators_(RightShift, >>) 00500 00501 _nemo_mapping_binary_operators_(IsEqual, ==) 00502 _nemo_mapping_binary_operators_(IsNotEqual, !=) 00503 _nemo_mapping_binary_operators_(IsLower, <) 00504 _nemo_mapping_binary_operators_(IsHigher, >) 00505 _nemo_mapping_binary_operators_(IsLowerEqual, <=) 00506 _nemo_mapping_binary_operators_(IsHigherEqual, >=) 00507 00508 _nemo_mapping_binary_operators_(LogicAnd, &&) 00509 _nemo_mapping_binary_operators_(LogicOr, ||) 00510 #endif 00511 00512 00513 00514 #ifndef NEMO_PARSED_BY_DOXYGEN 00515 // Non-type-changing unary operators 00516 #define _nemo_mapping_unary_operator_(Name, OP) \ 00517 template <class InType, class OutType> \ 00518 class Name##Mapping : public MappingDefinition<InType,OutType> { \ 00519 public: \ 00520 OutType evaluate(InType value) const{ \ 00521 return OP map->evaluate(value); \ 00522 } \ 00523 MappingDefinition<OutType,InType>* getInverse() const { \ 00524 IntrusivePtr<MappingDefinition<OutType,InType> > mapInv(map->getInverse()); \ 00525 IntrusivePtr<MappingDefinition<OutType,OutType> > innerInv( \ 00526 new Name##Mapping<OutType,OutType> ( \ 00527 IntrusivePtr<MappingDefinition<OutType,OutType> >(new Identity<OutType>()) \ 00528 ) \ 00529 ); \ 00530 return new detail::SequentialMapping<OutType,OutType,InType>(innerInv, mapInv); \ 00531 } \ 00532 Name##Mapping( const IntrusivePtr<MappingDefinition<InType,OutType> > &mapP ) \ 00533 : map(mapP) {} \ 00534 private: \ 00535 IntrusivePtr<MappingDefinition<InType,OutType> > map; \ 00536 }; \ 00537 template <class InType, class OutType> \ 00538 inline Mapping<InType,OutType> operator OP (const Mapping<InType,OutType> &m){ \ 00539 return Mapping<InType,OutType>(new Name##Mapping<InType,OutType>(m.getDefinition())); \ 00540 } 00541 #endif 00542 00543 #ifndef NEMO_PARSED_BY_DOXYGEN 00544 _nemo_mapping_unary_operator_(UnaryPlus, +) 00545 _nemo_mapping_unary_operator_(UnaryMinus, -) 00546 _nemo_mapping_unary_operator_(LogicNot, !) 00547 _nemo_mapping_unary_operator_(BitwiseNot, ~) 00548 #endif 00549 00550 00551 // inversion rules 00552 00553 // inlining helps against multiple definitions 00554 00555 #define _nemo_scalar_inversion_(Type) \ 00556 template <> inline Type leftMultInverse<>(const Type &value){return ((Type)1.0)/value;} \ 00557 template <> inline Type rightMultInverse<>(const Type &value){return ((Type)1.0)/value;} \ 00558 template <> inline Type leftDivideInverse<>(const Type &value){return value;} \ 00559 template <> inline Type rightDivideInverse<>(const Type &value){return ((Type)1.0)/value;} \ 00560 template <> inline Type leftAddInverse<>(const Type &value){return -value;} \ 00561 template <> inline Type rightAddInverse<>(const Type &value){return -value;} \ 00562 template <> inline Type leftSubtractInverse<>(const Type &value){return value;} \ 00563 template <> inline Type rightSubtractInverse<>(const Type &value){return -value;} 00564 00565 #ifndef NEMO_PARSED_BY_DOXYGEN 00566 _nemo_scalar_inversion_(float) 00567 _nemo_scalar_inversion_(double) 00568 _nemo_scalar_inversion_(long double) 00569 #endif 00570 00571 #define _nemo_signed_integer_inversion_(Type) \ 00572 template <> inline Type leftAddInverse<>(const Type &value){return -value;} \ 00573 template <> inline Type rightAddInverse<>(const Type &value){return -value;} \ 00574 template <> inline Type leftSubtractInverse<>(const Type &value){return value;} \ 00575 template <> inline Type rightSubtractInverse<>(const Type &value){return -value;} 00576 00577 #ifndef NEMO_PARSED_BY_DOXYGEN 00578 _nemo_signed_integer_inversion_(short) 00579 _nemo_signed_integer_inversion_(int) 00580 _nemo_signed_integer_inversion_(long int) 00581 #endif 00582 00583 00584 } // end namespace 00585 00586 #endif 00587
Generated on Mon Feb 25 12:49:59 2013 for NemoMath by
![doxygen](doxygen.png)