libqi  1.14.5
qi/atomic.hpp
00001 /*
00002  * Copyright (c) 2012 Aldebaran Robotics. All rights reserved.
00003  * Use of this source code is governed by a BSD-style license that can be
00004  * found in the COPYING file.
00005  */
00006 
00007 #pragma once
00008 
00009 #ifndef _LIBQI_QI_ATOMIC_HPP_
00010 #define _LIBQI_QI_ATOMIC_HPP_
00011 
00012 #ifdef _MSC_VER
00013 # include <windows.h>
00014 # pragma intrinsic(_InterlockedIncrement16)
00015 # pragma intrinsic(_InterlockedDecrement16)
00016 # pragma intrinsic(_InterlockedIncrement)
00017 # pragma intrinsic(_InterlockedDecrement)
00018 
00019 extern "C" long __cdecl _InterlockedIncrement(long volatile *);
00020 extern "C" long __cdecl _InterlockedDecrement(long volatile *);
00021 extern "C" short __cdecl _InterlockedIncrement16(short volatile *);
00022 extern "C" short __cdecl _InterlockedDecrement16(short volatile *);
00023 #endif
00024 
00025 #include <qi/config.hpp>
00026 
00027 namespace qi
00028 {
00029   template <typename T>
00030   class QI_API atomic
00031   {
00032   public:
00033     atomic()
00034       : _value(0)
00035     {
00036     }
00037 
00038     atomic(T value)
00039       : _value(value)
00040     {
00041     }
00042 
00043     /* prefix operators */
00044     T operator++();
00045     T operator--();
00046 
00047     T operator*()
00048     {
00049       return _value;
00050     }
00051 
00052   private:
00053     T _value;
00054   };
00055 
00056 #ifdef __GNUC__
00057     template <typename T>
00058     T atomic<T>::operator++()
00059     {
00060       return __sync_add_and_fetch(&_value, 1);
00061     }
00062 
00063     template <typename T>
00064     T atomic<T>::operator--()
00065     {
00066       return __sync_sub_and_fetch(&_value, 1);
00067     }
00068 #endif
00069 
00070 #ifdef _MSC_VER
00071   template<>
00072   inline short atomic<short>::operator++()
00073   {
00074     return _InterlockedIncrement16(&_value);
00075   }
00076 
00077   template<>
00078   inline short atomic<short>::operator--()
00079   {
00080     return _InterlockedDecrement16(&_value);
00081   }
00082 
00083   template <>
00084   inline long atomic<long>::operator++()
00085   {
00086     return _InterlockedIncrement(&_value);
00087   }
00088 
00089   template <>
00090   inline long atomic<long>::operator--()
00091   {
00092     return _InterlockedDecrement(&_value);
00093   }
00094 #endif
00095 }
00096 
00097 #endif // _LIBQI_QI_ATOMIC_HPP_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines