summaryrefslogtreecommitdiff
path: root/boost/interprocess
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess')
-rw-r--r--boost/interprocess/detail/os_file_functions.hpp6
-rw-r--r--boost/interprocess/detail/os_thread_functions.hpp22
-rwxr-xr-xboost/interprocess/detail/shared_dir_helpers.hpp14
-rw-r--r--boost/interprocess/detail/utilities.hpp24
-rw-r--r--boost/interprocess/detail/win32_api.hpp205
-rw-r--r--boost/interprocess/offset_ptr.hpp130
6 files changed, 274 insertions, 127 deletions
diff --git a/boost/interprocess/detail/os_file_functions.hpp b/boost/interprocess/detail/os_file_functions.hpp
index bcb9576a19..7a41868188 100644
--- a/boost/interprocess/detail/os_file_functions.hpp
+++ b/boost/interprocess/detail/os_file_functions.hpp
@@ -102,6 +102,9 @@ inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
inline bool create_directory(const char *path)
{ return winapi::create_directory(path); }
+inline bool remove_directory(const char *path)
+{ return winapi::remove_directory(path); }
+
inline bool get_temporary_path(char *buffer, std::size_t buf_len, std::size_t &required_len)
{
required_len = 0;
@@ -422,6 +425,9 @@ inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
inline bool create_directory(const char *path)
{ return ::mkdir(path, 0777) == 0 && ::chmod(path, 0777) == 0; }
+inline bool remove_directory(const char *path)
+{ return ::rmdir(path) == 0; }
+
inline bool get_temporary_path(char *buffer, std::size_t buf_len, std::size_t &required_len)
{
required_len = 5u;
diff --git a/boost/interprocess/detail/os_thread_functions.hpp b/boost/interprocess/detail/os_thread_functions.hpp
index 3ff0a402ba..8a0a47cc27 100644
--- a/boost/interprocess/detail/os_thread_functions.hpp
+++ b/boost/interprocess/detail/os_thread_functions.hpp
@@ -53,7 +53,12 @@
# include <sys/sysctl.h>
# endif
//According to the article "C/C++ tip: How to measure elapsed real time for benchmarking"
-# if defined(CLOCK_MONOTONIC_PRECISE) //BSD
+//Check MacOs first as macOS 10.12 SDK defines both CLOCK_MONOTONIC and
+//CLOCK_MONOTONIC_RAW and no clock_gettime.
+# if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
+# include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
+# define BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
+# elif defined(CLOCK_MONOTONIC_PRECISE) //BSD
# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_PRECISE
# elif defined(CLOCK_MONOTONIC_RAW) //Linux
# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW
@@ -61,9 +66,6 @@
# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_HIGHRES
# elif defined(CLOCK_MONOTONIC) //POSIX (AIX, BSD, Linux, Solaris)
# define BOOST_INTERPROCESS_CLOCK_MONOTONIC CLOCK_MONOTONIC
-# elif !defined(CLOCK_MONOTONIC) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
-# include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
-# define BOOST_INTERPROCESS_MATCH_ABSOLUTE_TIME
# else
# error "No high resolution steady clock in your system, please provide a patch"
# endif
@@ -112,8 +114,8 @@ inline bool equal_thread_id(OS_thread_id_t id1, OS_thread_id_t id2)
//return the system tick in ns
inline unsigned long get_system_tick_ns()
{
- unsigned long curres;
- winapi::set_timer_resolution(10000, 0, &curres);
+ unsigned long curres, ignore1, ignore2;
+ winapi::query_timer_resolution(&ignore1, &ignore2, &curres);
//Windows API returns the value in hundreds of ns
return (curres - 1ul)*100ul;
}
@@ -121,8 +123,8 @@ inline unsigned long get_system_tick_ns()
//return the system tick in us
inline unsigned long get_system_tick_us()
{
- unsigned long curres;
- winapi::set_timer_resolution(10000, 0, &curres);
+ unsigned long curres, ignore1, ignore2;
+ winapi::query_timer_resolution(&ignore1, &ignore2, &curres);
//Windows API returns the value in hundreds of ns
return (curres - 1ul)/10ul + 1ul;
}
@@ -132,8 +134,8 @@ typedef unsigned __int64 OS_highres_count_t;
inline unsigned long get_system_tick_in_highres_counts()
{
__int64 freq;
- unsigned long curres;
- winapi::set_timer_resolution(10000, 0, &curres);
+ unsigned long curres, ignore1, ignore2;
+ winapi::query_timer_resolution(&ignore1, &ignore2, &curres);
//Frequency in counts per second
if(!winapi::query_performance_frequency(&freq)){
//Tick resolution in ms
diff --git a/boost/interprocess/detail/shared_dir_helpers.hpp b/boost/interprocess/detail/shared_dir_helpers.hpp
index 5d4d1b3842..0fcd898dcb 100755
--- a/boost/interprocess/detail/shared_dir_helpers.hpp
+++ b/boost/interprocess/detail/shared_dir_helpers.hpp
@@ -124,15 +124,11 @@ inline void get_shared_dir_root(std::string &dir_path)
#endif
#ifdef BOOST_INTERPROCESS_SHARED_DIR_FUNC
-namespace boost {
- namespace interprocess {
- namespace ipcdetail {
- // When BOOST_INTERPROCESS_SHARED_DIR_FUNC is defined, users have to implement
- // get_shared_dir
- void get_shared_dir(std::string &shared_dir);
- }
- }
-}
+
+ // When BOOST_INTERPROCESS_SHARED_DIR_FUNC is defined, users have to implement
+ // get_shared_dir
+ void get_shared_dir(std::string &shared_dir);
+
#else
inline void get_shared_dir(std::string &shared_dir)
{
diff --git a/boost/interprocess/detail/utilities.hpp b/boost/interprocess/detail/utilities.hpp
index e1be2f1598..c1b23423c2 100644
--- a/boost/interprocess/detail/utilities.hpp
+++ b/boost/interprocess/detail/utilities.hpp
@@ -156,29 +156,29 @@ BOOST_INTERPROCESS_FORCEINLINE bool size_overflows(SizeType count)
return multiplication_overflows(SizeType(SztSizeOfType), count);
}
-template<class RawPointer>
-class pointer_uintptr_caster;
+template<class RawPointer, class OffsetType>
+class pointer_offset_caster;
-template<class T>
-class pointer_uintptr_caster<T*>
+template<class T, class OffsetType>
+class pointer_offset_caster<T*, OffsetType>
{
public:
- BOOST_INTERPROCESS_FORCEINLINE explicit pointer_uintptr_caster(uintptr_t sz)
- : m_uintptr(sz)
+ BOOST_INTERPROCESS_FORCEINLINE explicit pointer_offset_caster(OffsetType offset)
+ : m_offset(offset)
{}
- BOOST_INTERPROCESS_FORCEINLINE explicit pointer_uintptr_caster(const volatile T *p)
- : m_uintptr(reinterpret_cast<uintptr_t>(p))
+ BOOST_INTERPROCESS_FORCEINLINE explicit pointer_offset_caster(const volatile T *p)
+ : m_offset(reinterpret_cast<OffsetType>(p))
{}
- BOOST_INTERPROCESS_FORCEINLINE uintptr_t uintptr() const
- { return m_uintptr; }
+ BOOST_INTERPROCESS_FORCEINLINE OffsetType offset() const
+ { return m_offset; }
BOOST_INTERPROCESS_FORCEINLINE T* pointer() const
- { return reinterpret_cast<T*>(m_uintptr); }
+ { return reinterpret_cast<T*>(m_offset); }
private:
- uintptr_t m_uintptr;
+ OffsetType m_offset;
};
diff --git a/boost/interprocess/detail/win32_api.hpp b/boost/interprocess/detail/win32_api.hpp
index 02c7b42706..1ea8cec53d 100644
--- a/boost/interprocess/detail/win32_api.hpp
+++ b/boost/interprocess/detail/win32_api.hpp
@@ -31,9 +31,45 @@
#include <string>
#include <vector>
+//#define BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME
+//#define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
+//#define BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED
+
+#ifdef BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME
+# define BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME_VALUE 1
+#else
+# define BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME_VALUE 0
+#endif
+
+#ifdef BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
+# define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED_VALUE 1
+#else
+# define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED_VALUE 0
+#endif
+
+#ifdef BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED
+# define BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED_VALUE 1
+#else
+# define BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED_VALUE 0
+#endif
+
+#define BOOST_INTERPROCESS_BOOTSTAMP_VALUE_SUM \
+ (BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED_VALUE + \
+ BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED_VALUE + \
+ BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME_VALUE)
+
+#if 1 < BOOST_INTERPROCESS_BOOTSTAMP_VALUE_SUM
+# error "Only one of BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME, \
+ BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED and \
+ BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED can be defined"
+#endif
+
+#if 0 == BOOST_INTERPROCESS_BOOTSTAMP_VALUE_SUM
+# define BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
+#endif
+
#ifdef BOOST_USE_WINDOWS_H
#include <windows.h>
-
# if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME)
# include <wbemidl.h>
# include <objbase.h>
@@ -1162,6 +1198,23 @@ const unsigned long COINIT_MULTITHREADED_BIPC = 0x0;
const unsigned long COINIT_DISABLE_OLE1DDE_BIPC = 0x4;
const unsigned long COINIT_SPEED_OVER_MEMORY_BIPC = 0x4;
+// Registry types
+#define reg_none ( 0 ) // No value type
+#define reg_sz ( 1 ) // Unicode nul terminated string
+#define reg_expand_sz ( 2 ) // Unicode nul terminated string
+ // (with environment variable references)
+#define reg_binary ( 3 ) // Free form binary
+#define reg_dword ( 4 ) // 32-bit number
+#define reg_dword_little_endian ( 4 ) // 32-bit number (same as REG_DWORD)
+#define reg_dword_big_endian ( 5 ) // 32-bit number
+#define reg_link ( 6 ) // Symbolic Link (unicode)
+#define reg_multi_sz ( 7 ) // Multiple Unicode strings
+#define reg_resource_list ( 8 ) // Resource list in the resource map
+#define reg_full_resource_descriptor ( 9 ) // Resource list in the hardware description
+#define reg_resource_requirements_list ( 10 )
+#define reg_qword ( 11 ) // 64-bit number
+#define reg_qword_little_endian ( 11 ) // 64-bit number (same as reg_qword)
+
//If the user needs to change default COM initialization model,
//it can define BOOST_INTERPROCESS_WINDOWS_COINIT_MODEL to one of these:
@@ -1654,28 +1707,6 @@ inline bool get_boot_and_system_time(unsigned char (&bootsystemstamp) [BootAndSy
return true;
}
-inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s)
- //will write BootstampLength chars
-{
- if(s < (BootstampLength*2))
- return false;
- system_timeofday_information info;
- bool ret = get_system_time_of_day_information(info);
- if(!ret){
- return false;
- }
- const char Characters [] =
- { '0', '1', '2', '3', '4', '5', '6', '7'
- , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- std::size_t char_counter = 0;
- for(std::size_t i = 0; i != static_cast<std::size_t>(BootstampLength); ++i){
- bootstamp_str[char_counter++] = Characters[(info.Reserved1[i]&0xF0)>>4];
- bootstamp_str[char_counter++] = Characters[(info.Reserved1[i]&0x0F)];
- }
- s = BootstampLength*2;
- return true;
-}
-
//Writes the hexadecimal value of the buffer, in the wide character string.
//str must be twice length
inline void buffer_to_wide_str(const void *buf, std::size_t length, wchar_t *str)
@@ -1691,6 +1722,37 @@ inline void buffer_to_wide_str(const void *buf, std::size_t length, wchar_t *str
}
}
+//Writes the hexadecimal value of the buffer, in the narrow character string.
+//str must be twice length
+inline void buffer_to_narrow_str(const void *buf, std::size_t length, char *str)
+{
+ const char Characters [] =
+ { '0', '1', '2', '3', '4', '5', '6', '7'
+ , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ std::size_t char_counter = 0;
+ const char *chbuf = static_cast<const char *>(buf);
+ for(std::size_t i = 0; i != length; ++i){
+ str[char_counter++] = Characters[(chbuf[i]&0xF0)>>4];
+ str[char_counter++] = Characters[(chbuf[i]&0x0F)];
+ }
+}
+
+inline bool get_boot_time_str(char *bootstamp_str, std::size_t &s)
+ //will write BootstampLength chars
+{
+ if(s < (BootstampLength*2))
+ return false;
+ system_timeofday_information info;
+ bool ret = get_system_time_of_day_information(info);
+ if(!ret){
+ return false;
+ }
+
+ buffer_to_narrow_str(info.Reserved1, BootstampLength, bootstamp_str);
+ s = BootstampLength*2;
+ return true;
+}
+
inline bool get_boot_and_system_time_wstr(wchar_t *bootsystemstamp, std::size_t &s)
//will write BootAndSystemstampLength chars
{
@@ -1748,7 +1810,7 @@ class nt_query_mem_deleter
(SystemTimeOfDayInfoLength + sizeof(unsigned long) + sizeof(boost::uint32_t))*2;
public:
- nt_query_mem_deleter(std::size_t object_name_information_size)
+ explicit nt_query_mem_deleter(std::size_t object_name_information_size)
: m_size(object_name_information_size + rename_offset + rename_suffix)
, m_buf(new char [m_size])
{}
@@ -1786,7 +1848,7 @@ class nt_query_mem_deleter
class c_heap_deleter
{
public:
- c_heap_deleter(std::size_t size)
+ explicit c_heap_deleter(std::size_t size)
: m_buf(::malloc(size))
{}
@@ -1935,13 +1997,35 @@ struct reg_closer
~reg_closer(){ reg_close_key(key_); }
};
-inline void get_shared_documents_folder(std::string &s)
+inline bool get_registry_value_buffer(hkey key_type, const char *subkey_name, const char *value_name, void *buf, std::size_t &buflen)
{
- #if 1 //Original registry search code
+ bool bret = false;
+ hkey key;
+ if (reg_open_key_ex( key_type
+ , subkey_name
+ , 0
+ , key_query_value
+ , &key) == 0){
+ reg_closer key_closer(key);
+
+ //Obtain the value
+ unsigned long size = buflen;
+ unsigned long type;
+ buflen = 0;
+ bret = 0 == reg_query_value_ex( key, value_name, 0, &type, (unsigned char*)buf, &size);
+ if(bret)
+ buflen = (std::size_t)size;
+ }
+ return bret;
+}
+
+inline bool get_registry_value_string(hkey key_type, const char *subkey_name, const char *value_name, std::string &s)
+{
+ bool bret = false;
s.clear();
hkey key;
- if (reg_open_key_ex( hkey_local_machine
- , "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
+ if (reg_open_key_ex( key_type
+ , subkey_name
, 0
, key_query_value
, &key) == 0){
@@ -1950,19 +2034,28 @@ inline void get_shared_documents_folder(std::string &s)
//Obtain the value
unsigned long size;
unsigned long type;
- const char *const reg_value = "Common AppData";
- //long err = (*pRegQueryValue)( key, reg_value, 0, &type, 0, &size);
- long err = reg_query_value_ex( key, reg_value, 0, &type, 0, &size);
- if(!err){
+ long err = reg_query_value_ex( key, value_name, 0, &type, 0, &size);
+ if((reg_sz == type || reg_expand_sz != type) && !err){
//Size includes terminating NULL
s.resize(size);
- //err = (*pRegQueryValue)( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
- err = reg_query_value_ex( key, reg_value, 0, &type, (unsigned char*)(&s[0]), &size);
- if(!err)
+ err = reg_query_value_ex( key, value_name, 0, &type, (unsigned char*)(&s[0]), &size);
+ if(!err){
s.erase(s.end()-1);
+ bret = true;
+ }
(void)err;
}
}
+ return bret;
+}
+
+inline void get_shared_documents_folder(std::string &s)
+{
+ #if 1 //Original registry search code
+ get_registry_value_string( hkey_local_machine
+ , "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"
+ , "Common AppData"
+ , s);
#else //registry alternative: SHGetFolderPath
const int BIPC_CSIDL_COMMON_APPDATA = 0x0023; // All Users\Application Data
const int BIPC_CSIDL_FLAG_CREATE = 0x8000; // new for Win2K, or this in to force creation of folder
@@ -2175,7 +2268,9 @@ inline bool get_last_bootup_time( std::string& str )
return ret;
}
-#else
+#endif //BOOST_INTERPROCESS_BOOTSTAMP_IS_LASTBOOTUPTIME
+
+#if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED)
// Loop through the buffer and obtain the contents of the
// requested record in the buffer.
@@ -2271,7 +2366,41 @@ inline bool get_last_bootup_time(std::string &stamp)
return true;
}
-#endif
+#endif //BOOST_INTERPROCESS_BOOTSTAMP_IS_EVENTLOG_BASED
+
+#if defined(BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED)
+
+inline bool get_last_bootup_time(std::string &stamp)
+{
+ unsigned dword_val = 0;
+ std::size_t dword_size = sizeof(dword_val);
+ bool b_ret = get_registry_value_buffer( hkey_local_machine
+ , "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management\\PrefetchParameters"
+ , "BootId", &dword_val, dword_size);
+ if (b_ret)
+ {
+ char dword_str[sizeof(dword_val)*2u+1];
+ buffer_to_narrow_str(&dword_val, dword_size, dword_str);
+ dword_str[sizeof(dword_val)*2] = '\0';
+ stamp = dword_str;
+
+ b_ret = get_registry_value_buffer( hkey_local_machine
+ , "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Power"
+ , "HybridBootAnimationTime", &dword_val, dword_size);
+ //Old Windows versions have no HybridBootAnimationTime
+ if(b_ret)
+ {
+ buffer_to_narrow_str(&dword_val, dword_size, dword_str);
+ dword_str[sizeof(dword_val)*2] = '\0';
+ stamp += "_";
+ stamp += dword_str;
+ }
+ b_ret = true;
+ }
+ return b_ret;
+}
+
+#endif //BOOST_INTERPROCESS_BOOTSTAMP_IS_SESSION_MANAGER_BASED
inline bool is_directory(const char *path)
{
diff --git a/boost/interprocess/offset_ptr.hpp b/boost/interprocess/offset_ptr.hpp
index fca444eaa4..24b044adf4 100644
--- a/boost/interprocess/offset_ptr.hpp
+++ b/boost/interprocess/offset_ptr.hpp
@@ -23,6 +23,9 @@
#include <boost/interprocess/detail/workaround.hpp>
#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_constructible.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/interprocess/detail/utilities.hpp>
@@ -55,6 +58,7 @@ namespace ipcdetail {
union offset_ptr_internal
{
BOOST_STATIC_ASSERT(sizeof(OffsetType) >= sizeof(uintptr_t));
+ BOOST_STATIC_ASSERT(boost::is_integral<OffsetType>::value && boost::is_unsigned<OffsetType>::value);
explicit offset_ptr_internal(OffsetType off)
: m_offset(off)
@@ -81,20 +85,21 @@ namespace ipcdetail {
//
////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR
- BOOST_INTERPROCESS_FORCEINLINE void * offset_ptr_to_raw_pointer(const volatile void *this_ptr, uintptr_t offset)
+ template <class OffsetType>
+ BOOST_INTERPROCESS_FORCEINLINE void * offset_ptr_to_raw_pointer(const volatile void *this_ptr, OffsetType offset)
{
- typedef pointer_uintptr_caster<void*> caster_t;
+ typedef pointer_offset_caster<void*, OffsetType> caster_t;
#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_PTR
if(offset == 1){
return 0;
}
else{
- return caster_t(caster_t(this_ptr).uintptr() + offset).pointer();
+ return caster_t(caster_t(this_ptr).offset() + offset).pointer();
}
#else
- uintptr_t mask = offset == 1;
+ OffsetType mask = offset == 1;
--mask;
- uintptr_t target_offset = caster_t(this_ptr).uintptr() + offset;
+ OffsetType target_offset = caster_t(this_ptr).offset() + offset;
target_offset &= mask;
return caster_t(target_offset).pointer();
#endif
@@ -106,27 +111,28 @@ namespace ipcdetail {
//
////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF
- BOOST_INTERPROCESS_FORCEINLINE uintptr_t offset_ptr_to_offset(const volatile void *ptr, const volatile void *this_ptr)
+ template<class OffsetType>
+ BOOST_INTERPROCESS_FORCEINLINE OffsetType offset_ptr_to_offset(const volatile void *ptr, const volatile void *this_ptr)
{
- typedef pointer_uintptr_caster<void*> caster_t;
+ typedef pointer_offset_caster<void*, OffsetType> caster_t;
#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF
//offset == 1 && ptr != 0 is not legal for this pointer
if(!ptr){
return 1;
}
else{
- uintptr_t offset = caster_t(ptr).uintptr() - caster_t(this_ptr).uintptr();
+ OffsetType offset = caster_t(ptr).offset()- caster_t(this_ptr).offset();
BOOST_ASSERT(offset != 1);
return offset;
}
#else
- //const uintptr_t other = -uintptr_t(ptr != 0);
- //const uintptr_t offset = (caster_t(ptr).uintptr() - caster_t(this_ptr).uintptr()) & other;
- //return offset + uintptr_t(!other);
+ //const OffsetType other = -OffsetType(ptr != 0);
+ //const OffsetType offset = (caster_t(ptr).offset() - caster_t(this_ptr).offset()) & other;
+ //return offset + OffsetType(!other);
//
- uintptr_t offset = caster_t(ptr).uintptr() - caster_t(this_ptr).uintptr();
+ OffsetType offset = caster_t(ptr).offset() - caster_t(this_ptr).offset();
--offset;
- uintptr_t mask = uintptr_t(ptr == 0);
+ OffsetType mask = ptr == 0;
--mask;
offset &= mask;
return ++offset;
@@ -139,28 +145,29 @@ namespace ipcdetail {
//
////////////////////////////////////////////////////////////////////////
#define BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF_FROM_OTHER
- BOOST_INTERPROCESS_FORCEINLINE uintptr_t offset_ptr_to_offset_from_other
- (const volatile void *this_ptr, const volatile void *other_ptr, uintptr_t other_offset)
+ template<class OffsetType>
+ BOOST_INTERPROCESS_FORCEINLINE OffsetType offset_ptr_to_offset_from_other
+ (const volatile void *this_ptr, const volatile void *other_ptr, OffsetType other_offset)
{
- typedef pointer_uintptr_caster<void*> caster_t;
+ typedef pointer_offset_caster<void*, OffsetType> caster_t;
#ifndef BOOST_INTERPROCESS_OFFSET_PTR_BRANCHLESS_TO_OFF_FROM_OTHER
if(other_offset == 1){
return 1;
}
else{
- uintptr_t offset = caster_t(other_ptr).uintptr() - caster_t(this_ptr).uintptr() + other_offset;
+ OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset() + other_offset;
BOOST_ASSERT(offset != 1);
return offset;
}
#else
- uintptr_t mask = other_offset == 1;
+ OffsetType mask = other_offset == 1;
--mask;
- uintptr_t offset = caster_t(other_ptr).uintptr() - caster_t(this_ptr).uintptr();
+ OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset();
offset &= mask;
return offset + other_offset;
- //uintptr_t mask = -uintptr_t(other_offset != 1);
- //uintptr_t offset = caster_t(other_ptr).uintptr() - caster_t(this_ptr).uintptr();
+ //OffsetType mask = -OffsetType(other_offset != 1);
+ //OffsetType offset = caster_t(other_ptr).offset() - caster_t(this_ptr).offset();
//offset &= mask;
//return offset + other_offset;
#endif
@@ -215,9 +222,9 @@ namespace ipcdetail {
//!
//!<b>Note</b>: offset_ptr uses implementation defined properties, present in most platforms, for
//!performance reasons:
-//! - Assumes that uintptr_t representation of nullptr is (uintptr_t)zero.
-//! - Assumes that incrementing a uintptr_t obtained from a pointer is equivalent
-//! to incrementing the pointer and then converting it back to uintptr_t.
+//! - Assumes that OffsetType representation of nullptr is (OffsetType)zero.
+//! - Assumes that incrementing a OffsetType obtained from a pointer is equivalent
+//! to incrementing the pointer and then converting it back to OffsetType.
template <class PointedType, class DifferenceType, class OffsetType, std::size_t OffsetAlignment>
class offset_ptr
{
@@ -251,7 +258,7 @@ class offset_ptr
//!Constructor from raw pointer (allows "0" pointer conversion).
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(pointer ptr) BOOST_NOEXCEPT
- : internal(static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset(ptr, this)))
+ : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(ptr, this))
{}
//!Constructor from other pointer.
@@ -259,78 +266,81 @@ class offset_ptr
template <class T>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr( T *ptr
, typename ipcdetail::enable_if< ::boost::is_convertible<T*, PointedType*> >::type * = 0) BOOST_NOEXCEPT
- : internal(static_cast<OffsetType>
- (ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(ptr), this)))
+ : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr), this))
{}
//!Constructor from other offset_ptr
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr& ptr) BOOST_NOEXCEPT
- : internal(static_cast<OffsetType>
- (ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset)))
+ : internal(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset))
{}
- //!Constructor from other offset_ptr. If pointers of pointee types are
- //!convertible, offset_ptrs will be convertibles. Never throws.
+ //!Constructor from other offset_ptr. Only takes part in overload resolution
+ //!if T2* is convertible to PointedType*. Never throws.
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
, typename ipcdetail::enable_if_convertible_equal_address<T2, PointedType>::type* = 0
#endif
) BOOST_NOEXCEPT
- : internal(static_cast<OffsetType>
- (ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset())))
+ : internal(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset()))
{}
#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
- //!Constructor from other offset_ptr. If pointers of pointee types are
- //!convertible, offset_ptrs will be convertibles. Never throws.
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr( const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
, typename ipcdetail::enable_if_convertible_unequal_address<T2, PointedType>::type* = 0) BOOST_NOEXCEPT
- : internal(static_cast<OffsetType>
- (ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(ptr.get()), this)))
+ : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
{}
#endif
+ //!Constructor from other offset_ptr. Only takes part in overload resolution
+ //!if PointedType* is constructible from T2* other than via a conversion (e.g. cast to a derived class). Never throws.
+ template<class T2>
+ BOOST_INTERPROCESS_FORCEINLINE explicit offset_ptr(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr
+ #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ , typename ipcdetail::enable_if_c<
+ !::boost::is_convertible<T2*, PointedType*>::value && ::boost::is_constructible<T2*, PointedType*>::value
+ >::type * = 0
+ #endif
+ ) BOOST_NOEXCEPT
+ : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this))
+ {}
+
//!Emulates static_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::static_cast_tag) BOOST_NOEXCEPT
- : internal(static_cast<OffsetType>
- (ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(r.get()), this)))
+ : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(r.get()), this))
{}
//!Emulates const_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::const_cast_tag) BOOST_NOEXCEPT
- : internal(static_cast<OffsetType>
- (ipcdetail::offset_ptr_to_offset(const_cast<PointedType*>(r.get()), this)))
+ : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(const_cast<PointedType*>(r.get()), this))
{}
//!Emulates dynamic_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::dynamic_cast_tag) BOOST_NOEXCEPT
- : internal(static_cast<OffsetType>
- (ipcdetail::offset_ptr_to_offset(dynamic_cast<PointedType*>(r.get()), this)))
+ : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(dynamic_cast<PointedType*>(r.get()), this))
{}
//!Emulates reinterpret_cast operator.
//!Never throws.
template<class T2, class P2, class O2, std::size_t A2>
BOOST_INTERPROCESS_FORCEINLINE offset_ptr(const offset_ptr<T2, P2, O2, A2> & r, ipcdetail::reinterpret_cast_tag) BOOST_NOEXCEPT
- : internal(static_cast<OffsetType>
- (ipcdetail::offset_ptr_to_offset(reinterpret_cast<PointedType*>(r.get()), this)))
+ : internal(ipcdetail::offset_ptr_to_offset<OffsetType>(reinterpret_cast<PointedType*>(r.get()), this))
{}
//!Obtains raw pointer from offset.
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE pointer get() const BOOST_NOEXCEPT
- { return (pointer)ipcdetail::offset_ptr_to_raw_pointer(this, this->internal.m_offset); }
+ { return static_cast<pointer>(ipcdetail::offset_ptr_to_raw_pointer(this, this->internal.m_offset)); }
BOOST_INTERPROCESS_FORCEINLINE offset_type get_offset() const BOOST_NOEXCEPT
{ return this->internal.m_offset; }
@@ -358,8 +368,7 @@ class offset_ptr
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (pointer from) BOOST_NOEXCEPT
{
- this->internal.m_offset =
- static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset(from, this));
+ this->internal.m_offset = ipcdetail::offset_ptr_to_offset<OffsetType>(from, this);
return *this;
}
@@ -367,8 +376,7 @@ class offset_ptr
//!Never throws.
BOOST_INTERPROCESS_FORCEINLINE offset_ptr& operator= (const offset_ptr & ptr) BOOST_NOEXCEPT
{
- this->internal.m_offset =
- static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset));
+ this->internal.m_offset = ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.internal.m_offset);
return *this;
}
@@ -444,9 +452,17 @@ class offset_ptr
//!Compatibility with pointer_traits
//!
+ #if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class U>
struct rebind
{ typedef offset_ptr<U, DifferenceType, OffsetType, OffsetAlignment> other; };
+ #else
+ template <class U>
+ using rebind = offset_ptr<U, DifferenceType, OffsetType, OffsetAlignment>;
+ #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ typedef offset_ptr<PointedType, DifferenceType, OffsetType, OffsetAlignment> other;
+ #endif //BOOST_INTERPROCESS_DOXYGEN_INVOKED
+ #endif
//!Compatibility with pointer_traits
//!
@@ -546,15 +562,13 @@ class offset_ptr
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr, ipcdetail::bool_<true>) BOOST_NOEXCEPT
{ //no need to pointer adjustment
- this->internal.m_offset =
- static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset_from_other(this, &ptr, ptr.get_offset()));
+ this->internal.m_offset = ipcdetail::offset_ptr_to_offset_from_other<OffsetType>(this, &ptr, ptr.get_offset());
}
template<class T2>
BOOST_INTERPROCESS_FORCEINLINE void assign(const offset_ptr<T2, DifferenceType, OffsetType, OffsetAlignment> &ptr, ipcdetail::bool_<false>) BOOST_NOEXCEPT
{ //we must convert to raw before calculating the offset
- this->internal.m_offset =
- static_cast<OffsetType>(ipcdetail::offset_ptr_to_offset(static_cast<PointedType*>(ptr.get()), this));
+ this->internal.m_offset = ipcdetail::offset_ptr_to_offset<OffsetType>(static_cast<PointedType*>(ptr.get()), this);
}
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
@@ -692,7 +706,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
typedef boost::interprocess::offset_ptr<T, P, O, A> pointer;
//Bits are stored in the lower bits of the pointer except the LSB,
//because this bit is used to represent the null pointer.
- static const uintptr_t Mask = ((uintptr_t(1) << uintptr_t(NumBits)) - uintptr_t(1)) << uintptr_t(1);
+ static const O Mask = ((static_cast<O>(1) << NumBits) - static_cast<O>(1)) << 1;
BOOST_STATIC_ASSERT(0 ==(Mask&1));
//We must ALWAYS take argument "n" by reference as a copy of a null pointer
@@ -701,7 +715,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
BOOST_INTERPROCESS_FORCEINLINE static pointer get_pointer(const pointer &n) BOOST_NOEXCEPT
{
pointer p;
- O const tmp_off = n.priv_offset() & O(~Mask);
+ O const tmp_off = n.priv_offset() & ~Mask;
p.priv_offset() = boost::interprocess::ipcdetail::offset_ptr_to_offset_from_other(&p, &n, tmp_off);
return p;
}
@@ -709,7 +723,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
BOOST_INTERPROCESS_FORCEINLINE static void set_pointer(pointer &n, const pointer &p) BOOST_NOEXCEPT
{
BOOST_ASSERT(0 == (get_bits)(p));
- O const stored_bits = O(n.priv_offset() & Mask);
+ O const stored_bits = n.priv_offset() & Mask;
n = p;
n.priv_offset() |= stored_bits;
}
@@ -723,7 +737,7 @@ struct pointer_plus_bits<boost::interprocess::offset_ptr<T, P, O, A>, NumBits>
{
BOOST_ASSERT(b < (std::size_t(1) << NumBits));
O tmp = n.priv_offset();
- tmp &= O(~Mask);
+ tmp &= ~Mask;
tmp |= O(b << 1u);
n.priv_offset() = tmp;
}