Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-08 08:23:05

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
0012 #define BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 0018 ">#
0019 #if defined(BOOST_HAS_PRAGMA_ONCE)
0020 #  pragma once
0021 #endif
0022 
0023 #include <boost/interprocess/detail/config_begin.hpp>
0024 #include <boost/interprocess/detail/workaround.hpp>
0025 
0026 // interprocess
0027 #include <boost/interprocess/exceptions.hpp>
0028 // interprocess/detail
0029 #include <boost/interprocess/detail/type_traits.hpp>
0030 #include <boost/interprocess/detail/utilities.hpp>
0031 // container/detail
0032 #include <boost/container/detail/type_traits.hpp> //alignment_of
0033 #include <boost/container/detail/minimal_char_traits_header.hpp>
0034 #include <boost/container/detail/placement_new.hpp>
0035 // intrusive
0036 #include <boost/intrusive/pointer_traits.hpp>
0037 // move/detail
0038 #include <boost/move/detail/type_traits.hpp> //make_unsigned
0039 #include <boost/move/detail/force_ptr.hpp>
0040 // other boost
0041 #include <boost/assert.hpp>   //BOOST_ASSERT
0042 // std
0043 #include <cstddef>   //std::size_t
0044 
0045 
0046 namespace boost{
0047 namespace interprocess{
0048 
0049 template<class MemoryManager>
0050 class segment_manager_base;
0051 
0052 //!An integer that describes the type of the
0053 //!instance constructed in memory
0054 enum instance_type {   anonymous_type, named_type, unique_type, max_allocation_type };
0055 
0056 namespace ipcdetail{
0057 
0058 template<class MemoryAlgorithm>
0059 class mem_algo_deallocator
0060 {
0061    void *            m_ptr;
0062    MemoryAlgorithm & m_algo;
0063 
0064    public:
0065    mem_algo_deallocator(void *ptr, MemoryAlgorithm &algo)
0066       :  m_ptr(ptr), m_algo(algo)
0067    {}
0068 
0069    void release()
0070    {  m_ptr = 0;  }
0071 
0072    ~mem_algo_deallocator()
0073    {  if(m_ptr) m_algo.deallocate(m_ptr);  }
0074 };
0075 
0076 #if !defined(BOOST_INTERPROCESS_SEGMENT_MANAGER_ABI)
0077 #define BOOST_INTERPROCESS_SEGMENT_MANAGER_ABI 2
0078 #endif   //#if !defined(BOOST_INTERPROCESS_SEGMENT_MANAGER_ABI)
0079 
0080 #if (BOOST_INTERPROCESS_SEGMENT_MANAGER_ABI == 1)
0081 
0082 template<class size_type>
0083 struct block_header
0084 {
0085    private:
0086    const size_type      m_value_bytes;
0087    const unsigned short m_num_char;
0088    const unsigned char  m_value_alignment;
0089    const unsigned char  m_alloc_type_sizeof_char;
0090 
0091    public:
0092    typedef std::size_t name_len_t;
0093 
0094    block_header(size_type val_bytes
0095                ,size_type val_alignment
0096                ,unsigned char al_type
0097                ,std::size_t szof_char
0098                ,std::size_t num_char
0099                )
0100       :  m_value_bytes(val_bytes)
0101       ,  m_num_char((unsigned short)num_char)
0102       ,  m_value_alignment((unsigned char)val_alignment)
0103       ,  m_alloc_type_sizeof_char( (unsigned char)((al_type << 5u) | ((unsigned char)szof_char & 0x1F)) )
0104    {};
0105    
0106    template<std::size_t>
0107    size_type total_anonymous_size() const
0108    {
0109       return this->value_offset() + m_value_bytes;
0110    }
0111 
0112    template<std::size_t, class>
0113    size_type total_named_size(std::size_t namelen) const
0114    {
0115       (void)namelen;
0116       BOOST_ASSERT(namelen == m_num_char);
0117       return name_offset() + (m_num_char+1u)*sizeof_char();
0118    }
0119 
0120    template<std::size_t, class, class Header>
0121    size_type total_named_size_with_header(std::size_t namelen) const
0122    {
0123       BOOST_ASSERT(namelen == m_num_char);
0124       return get_rounded_size
0125                ( size_type(sizeof(Header))
0126             , size_type(::boost::container::dtl::alignment_of<block_header<size_type> >::value))
0127            + this->template total_named_size<0, char>(namelen);
0128    }
0129 
0130    size_type value_bytes() const
0131    {  return m_value_bytes;   }
0132 
0133    unsigned char alloc_type() const
0134    {  return (m_alloc_type_sizeof_char >> 5u)&(unsigned char)0x7;  }
0135 
0136    unsigned char sizeof_char() const
0137    {  return m_alloc_type_sizeof_char & (unsigned char)0x1F;  }
0138 
0139    template<class CharType>
0140    CharType *name() const
0141    {
0142       return const_cast<CharType*>(move_detail::force_ptr<const CharType*>
0143          (reinterpret_cast<const char*>(this) + name_offset()));
0144    }
0145 
0146    unsigned short name_length() const
0147    {  return m_num_char;   }
0148 
0149    void *value() const
0150    {
0151       return const_cast<char*>((reinterpret_cast<const char*>(this) + this->value_offset()));
0152    }
0153 
0154    template<class T>
0155    static block_header *block_header_from_value(T *value)
0156    {
0157       //      BOOST_ASSERT(is_ptr_aligned(value, algn));
0158       const std::size_t algn = ::boost::container::dtl::alignment_of<T>::value;
0159       block_header* hdr =
0160          const_cast<block_header*>
0161          (move_detail::force_ptr<const block_header*>(reinterpret_cast<const char*>(value) -
0162             get_rounded_size(sizeof(block_header), algn)));
0163 
0164       //Some sanity checks
0165       BOOST_ASSERT(hdr->m_value_alignment == algn);
0166       BOOST_ASSERT(hdr->m_value_bytes % sizeof(T) == 0);
0167       return hdr;
0168    }
0169 
0170    template<class Header>
0171    static block_header *from_first_header(Header *header)
0172    {
0173       block_header * hdr =
0174          move_detail::force_ptr<block_header*>(reinterpret_cast<char*>(header) +
0175        get_rounded_size( size_type(sizeof(Header))
0176                        , size_type(::boost::container::dtl::alignment_of<block_header >::value)));
0177       //Some sanity checks
0178       return hdr;
0179    }
0180 
0181    template<class Header>
0182    static const block_header *from_first_header(const Header *header)
0183    {  return from_first_header(const_cast<Header*>(header));   }
0184 
0185    template<class Header>
0186    static Header *to_first_header(block_header *bheader)
0187    {
0188       Header * hdr =
0189          move_detail::force_ptr<Header*>(reinterpret_cast<char*>(bheader) -
0190        get_rounded_size( size_type(sizeof(Header))
0191                        , size_type(::boost::container::dtl::alignment_of<block_header >::value)));
0192       //Some sanity checks
0193       return hdr;
0194    }
0195 
0196    template<std::size_t>
0197    static size_type front_space_without_header()
0198    {  return 0u;  }
0199 
0200    template<std::size_t, class>
0201    static size_type front_space_with_header()
0202    {  return 0u;  }
0203 
0204    void store_name_length(std::size_t)
0205    {}
0206 
0207    private:
0208    size_type value_offset() const
0209    {
0210       return get_rounded_size(size_type(sizeof(block_header)), size_type(m_value_alignment));
0211    }
0212 
0213    size_type name_offset() const
0214    {
0215       return this->value_offset() + get_rounded_size(size_type(m_value_bytes), size_type(sizeof_char()));
0216    }
0217 };
0218 
0219 #elif (BOOST_INTERPROCESS_SEGMENT_MANAGER_ABI == 2)
0220 
0221 template <class BlockHeader, class Header>
0222 struct sm_between_headers
0223 {
0224    BOOST_STATIC_CONSTEXPR std::size_t value
0225       = sizeof(Header)
0226       + ct_rounded_size< sizeof(BlockHeader), boost::move_detail::alignment_of<Header>::value>::value
0227       - sizeof(BlockHeader);
0228 };
0229 
0230 template <std::size_t TypeAlignment, class BlockHeader, class Header>
0231 struct sg_offsets_with_header
0232 {
0233    private:
0234    BOOST_STATIC_CONSTEXPR std::size_t between_headers = sm_between_headers<BlockHeader, Header>::value;
0235    BOOST_STATIC_CONSTEXPR std::size_t both_headers = between_headers + sizeof(BlockHeader);
0236    BOOST_STATIC_CONSTEXPR std::size_t total_prefix = ct_rounded_size<both_headers, TypeAlignment>::value;
0237 
0238    public:
0239    BOOST_STATIC_CONSTEXPR std::size_t block_header_prefix = total_prefix - sizeof(BlockHeader);
0240    BOOST_STATIC_CONSTEXPR std::size_t front_space = total_prefix - both_headers;
0241 
0242    BOOST_INTERPROCESS_STATIC_ASSERT((total_prefix % TypeAlignment) == 0);
0243    BOOST_INTERPROCESS_STATIC_ASSERT((front_space % boost::move_detail::alignment_of<Header>::value) == 0);
0244    BOOST_INTERPROCESS_STATIC_ASSERT((block_header_prefix % boost::move_detail::alignment_of<BlockHeader>::value) == 0);
0245    BOOST_INTERPROCESS_STATIC_ASSERT(total_prefix == (sizeof(BlockHeader) + sizeof(Header) + front_space + (between_headers - sizeof(Header))));
0246 };
0247 
0248 template <std::size_t TypeAlignment, class BlockHeader>
0249 struct sg_offsets_without_header
0250 {
0251    BOOST_STATIC_CONSTEXPR std::size_t total_prefix = ct_rounded_size<sizeof(BlockHeader), TypeAlignment>::value;
0252 
0253    public:
0254    BOOST_STATIC_CONSTEXPR std::size_t block_header_prefix = total_prefix - sizeof(BlockHeader);
0255    BOOST_STATIC_CONSTEXPR std::size_t front_space = block_header_prefix;
0256 };
0257 
0258 template<class size_type>
0259 struct block_header
0260 {
0261    private:
0262    const size_type  m_alloc_type  : 2;
0263    const size_type  m_value_bytes : sizeof(size_type)*CHAR_BIT - 2u;
0264 
0265    public:
0266    typedef unsigned short name_len_t;
0267 
0268    block_header(size_type val_bytes
0269                ,size_type 
0270                ,unsigned char al_type
0271                ,std::size_t
0272                ,std::size_t
0273                )
0274       : m_alloc_type(al_type & 3u)
0275       , m_value_bytes(val_bytes & (~size_type(0) >> 2u))
0276    {};
0277 
0278    template<std::size_t TypeAlignment>
0279    size_type total_anonymous_size() const
0280    {
0281       BOOST_CONSTEXPR_OR_CONST std::size_t block_header_prefix =
0282          sg_offsets_without_header<TypeAlignment, block_header>::block_header_prefix;
0283       return block_header_prefix + this->value_offset() + m_value_bytes;
0284    }
0285 
0286    template<std::size_t TypeAlignment, class CharType>
0287    size_type total_named_size(std::size_t namelen) const
0288    {
0289       BOOST_CONSTEXPR_OR_CONST std::size_t block_header_prefix =
0290          sg_offsets_without_header<TypeAlignment, block_header>::block_header_prefix;
0291       return block_header_prefix
0292          + name_offset< ::boost::move_detail::alignment_of<CharType>::value>()
0293          + (namelen + 1u) * sizeof(CharType);
0294    }
0295 
0296    template<std::size_t TypeAlignment, class CharType, class Header>
0297    size_type total_named_size_with_header(std::size_t namelen) const
0298    {
0299       typedef sg_offsets_with_header<TypeAlignment, block_header, Header> offsets_t;
0300       return offsets_t::block_header_prefix
0301          + name_offset< ::boost::move_detail::alignment_of<CharType>::value>()
0302          + (namelen + 1u) * sizeof(CharType);
0303    }
0304 
0305    size_type value_bytes() const
0306    {  return m_value_bytes;   }
0307 
0308    unsigned char alloc_type() const
0309    {  return m_alloc_type;  }
0310 
0311    template<class CharType>
0312    CharType *name() const
0313    {
0314       return const_cast<CharType*>(move_detail::force_ptr<const CharType*>
0315          (reinterpret_cast<const char*>(this) +
0316           this->template name_offset< ::boost::move_detail::alignment_of<CharType>::value>()));
0317    }
0318 
0319    name_len_t name_length() const
0320    {
0321       if(m_alloc_type == anonymous_type)
0322          return 0;
0323       return *(move_detail::force_ptr<const name_len_t*>
0324          (reinterpret_cast<const char*>(this) + this->name_length_offset()));
0325    }
0326 
0327    void *value() const
0328    {  return const_cast<char*>((reinterpret_cast<const char*>(this) + this->value_offset()));  }
0329 
0330    template<class T>
0331    static block_header *block_header_from_value(T *value)
0332    {
0333       BOOST_ASSERT(is_ptr_aligned(value, ::boost::container::dtl::alignment_of<T>::value));
0334       block_header* hdr =
0335          const_cast<block_header*>
0336             (move_detail::force_ptr<const block_header*>
0337                (reinterpret_cast<const char*>(value) - value_offset()));
0338 
0339       //Some sanity checks
0340       BOOST_ASSERT(hdr->m_value_bytes % sizeof(T) == 0);
0341       return hdr;
0342    }
0343 
0344    template<class Header>
0345    static block_header *from_first_header(Header *header)
0346    {
0347       BOOST_ASSERT(is_ptr_aligned(header));
0348       block_header * const hdr = move_detail::force_ptr<block_header*>(
0349             reinterpret_cast<char*>(header) + sm_between_headers<block_header, Header>::value);
0350       //Some sanity checks
0351       BOOST_ASSERT(is_ptr_aligned(hdr));
0352       return hdr;
0353    }
0354 
0355    template<class Header>
0356    static const block_header *from_first_header(const Header *header)
0357    {  return from_first_header(const_cast<Header*>(header));   }
0358 
0359    template<class Header>
0360    static Header *to_first_header(block_header *bheader)
0361    {
0362       BOOST_ASSERT(is_ptr_aligned(bheader));
0363       Header * hdr = move_detail::force_ptr<Header*>(
0364          reinterpret_cast<char*>(bheader) - sm_between_headers<block_header, Header>::value);
0365       //Some sanity checks
0366       BOOST_ASSERT(is_ptr_aligned(hdr));
0367       return hdr;
0368    }
0369 
0370    template<std::size_t TypeAlignment, class Header>
0371    static size_type front_space_with_header()
0372    {  return sg_offsets_with_header<TypeAlignment, block_header, Header>::front_space; }
0373 
0374    template<std::size_t TypeAlignment>
0375    static size_type front_space_without_header()
0376    {  return sg_offsets_without_header<TypeAlignment, block_header>::front_space; }
0377 
0378    void store_name_length(name_len_t namelen)
0379    {
0380       ::new( reinterpret_cast<char*>(this) + this->name_length_offset()
0381            , boost_container_new_t()
0382            ) name_len_t(namelen);
0383    }
0384 
0385    private:
0386 
0387    static size_type value_offset()
0388    {  return size_type(sizeof(block_header));   }
0389 
0390    template<std::size_t CharAlign>
0391    size_type name_offset() const
0392    {  return get_rounded_size(this->name_length_offset()+sizeof(name_len_t), CharAlign);  }
0393 
0394    size_type name_length_offset() const
0395    {
0396       return this->value_offset() + get_rounded_size(m_value_bytes, ::boost::move_detail::alignment_of<name_len_t>::value);
0397    }
0398 };
0399 
0400 
0401 #else //(BOOST_INTERPROCESS_SEGMENT_MANAGER_ABI == )
0402 
0403 #error "Incorrect BOOST_INTERPROCESS_SEGMENT_MANAGER_ABI value!"
0404 
0405 #endif
0406 
0407 template<class CharT>
0408 struct intrusive_compare_key
0409 {
0410    typedef CharT char_type;
0411 
0412    intrusive_compare_key(const CharT* str_, std::size_t len_)
0413       : mp_str(str_), m_len(len_)
0414    {}
0415 
0416    const CharT* str() const
0417    {
0418       return mp_str;
0419    }
0420 
0421    std::size_t len() const
0422    {
0423       return m_len;
0424    }
0425 
0426    const CharT* mp_str;
0427    std::size_t    m_len;
0428 };
0429 
0430 //!This struct indicates an anonymous object creation
0431 //!allocation
0432 template<instance_type type>
0433 class instance_t
0434 {
0435    instance_t(){}
0436 };
0437 
0438 template<class T>
0439 struct char_if_void
0440 {
0441    typedef T type;
0442 };
0443 
0444 template<>
0445 struct char_if_void<void>
0446 {
0447    typedef char type;
0448 };
0449 
0450 typedef instance_t<anonymous_type>  anonymous_instance_t;
0451 typedef instance_t<unique_type>     unique_instance_t;
0452 
0453 
0454 template<class Hook, class CharType, class SizeType>
0455 struct intrusive_value_type_impl
0456    :  public Hook
0457 {
0458    private:
0459    //Non-copyable
0460    intrusive_value_type_impl(const intrusive_value_type_impl &);
0461    intrusive_value_type_impl& operator=(const intrusive_value_type_impl &);
0462 
0463    public:
0464    typedef CharType char_type;
0465    typedef SizeType size_type;
0466    typedef block_header<size_type> block_header_t;
0467 
0468    intrusive_value_type_impl(){}
0469 
0470    CharType *name() const
0471    {  return get_block_header()->template name<CharType>(); }
0472 
0473    unsigned short name_length() const
0474    {  return get_block_header()->name_length(); }
0475 
0476    void *value() const
0477    {  return get_block_header()->value(); }
0478 
0479    private:
0480    const block_header_t *get_block_header() const
0481    {  return block_header_t::from_first_header(this); }
0482 };
0483 
0484 template<class CharType>
0485 class char_ptr_holder
0486 {
0487    public:
0488    char_ptr_holder(const CharType *name)
0489       : m_name(name)
0490    {}
0491 
0492    char_ptr_holder(const anonymous_instance_t *)
0493       : m_name(static_cast<CharType*>(0))
0494    {}
0495 
0496    char_ptr_holder(const unique_instance_t *)
0497       : m_name(reinterpret_cast<CharType*>(-1))
0498    {}
0499 
0500    operator const CharType *()
0501    {  return m_name;  }
0502 
0503    const CharType *get() const
0504    {  return m_name;  }
0505 
0506    bool is_unique() const
0507    {  return m_name == reinterpret_cast<CharType*>(-1);  }
0508 
0509    bool is_anonymous() const
0510    {  return m_name == static_cast<CharType*>(0);  }
0511 
0512    private:
0513    const CharType *m_name;
0514 };
0515 
0516 //!The key of the the named allocation information index. Stores an offset pointer
0517 //!to a null terminated string and the length of the string to speed up sorting
0518 template<class CharT, class VoidPointer>
0519 struct index_key
0520 {
0521    typedef typename boost::intrusive::
0522       pointer_traits<VoidPointer>::template
0523          rebind_pointer<const CharT>::type               const_char_ptr_t;
0524    typedef CharT                                         char_type;
0525    typedef typename boost::intrusive::pointer_traits<const_char_ptr_t>::difference_type difference_type;
0526    typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type;
0527 
0528    private:
0529    //Offset pointer to the object's name
0530    const_char_ptr_t  mp_str;
0531    //Length of the name buffer (null NOT included)
0532    size_type         m_len;
0533    public:
0534 
0535    //!Constructor of the key
0536    index_key (const char_type *nm, size_type length)
0537       : mp_str(nm), m_len(length)
0538    {}
0539 
0540    //!Less than function for index ordering
0541    bool operator < (const index_key & right) const
0542    {
0543       return (m_len < right.m_len) ||
0544                (m_len == right.m_len &&
0545                 std::char_traits<char_type>::compare
0546                   (to_raw_pointer(mp_str),to_raw_pointer(right.mp_str), m_len) < 0);
0547    }
0548 
0549    //!Equal to function for index ordering
0550    bool operator == (const index_key & right) const
0551    {
0552       return   m_len == right.m_len &&
0553                std::char_traits<char_type>::compare
0554                   (to_raw_pointer(mp_str), to_raw_pointer(right.mp_str), m_len) == 0;
0555    }
0556 
0557    void name(const CharT *nm)
0558    {  mp_str = nm; }
0559 
0560    void name_length(size_type len)
0561    {  m_len = len; }
0562 
0563    const CharT *name() const
0564    {  return to_raw_pointer(mp_str); }
0565 
0566    size_type name_length() const
0567    {  return m_len; }
0568 };
0569 
0570 //!The index_data stores a pointer to a buffer and the element count needed
0571 //!to know how many destructors must be called when calling destroy
0572 template<class VoidPointer>
0573 struct index_data
0574 {
0575    typedef VoidPointer void_pointer;
0576    void_pointer    m_ptr;
0577    explicit index_data(void *ptr) : m_ptr(ptr){}
0578 
0579    void *value() const
0580    {  return static_cast<void*>(to_raw_pointer(m_ptr));  }
0581 };
0582 
0583 template<class MemoryAlgorithm>
0584 struct segment_manager_base_type
0585 {  typedef segment_manager_base<MemoryAlgorithm> type;   };
0586 
0587 template<class CharT, class MemoryAlgorithm>
0588 struct index_config
0589 {
0590    typedef typename MemoryAlgorithm::void_pointer        void_pointer;
0591    typedef CharT                                         char_type;
0592    typedef index_key<CharT, void_pointer>                key_type;
0593    typedef index_data<void_pointer>                      mapped_type;
0594    typedef typename segment_manager_base_type
0595       <MemoryAlgorithm>::type                            segment_manager_base;
0596 
0597    template<class HeaderBase>
0598    struct intrusive_value_type
0599    {
0600       typedef intrusive_value_type_impl
0601          < HeaderBase
0602          , CharT
0603          , typename segment_manager_base::size_type
0604          >  type;
0605    };
0606 
0607    typedef intrusive_compare_key<CharT>                  compare_key_type;
0608 };
0609 
0610 template<class Iterator, bool intrusive>
0611 class segment_manager_iterator_value_adaptor
0612 {
0613    typedef typename Iterator::value_type        iterator_val_t;
0614    typedef typename iterator_val_t::char_type   char_type;
0615 
0616    public:
0617    segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val)
0618       :  m_val(&val)
0619    {}
0620 
0621    const char_type *name() const
0622    {  return m_val->name(); }
0623 
0624    unsigned short name_length() const
0625    {  return m_val->name_length(); }
0626 
0627    const void *value() const
0628    {  return m_val->value(); }
0629 
0630    const typename Iterator::value_type *m_val;
0631 };
0632 
0633 
0634 template<class Iterator>
0635 class segment_manager_iterator_value_adaptor<Iterator, false>
0636 {
0637    typedef typename Iterator::value_type        iterator_val_t;
0638    typedef typename iterator_val_t::first_type  first_type;
0639    typedef typename iterator_val_t::second_type second_type;
0640    typedef typename first_type::char_type       char_type;
0641    typedef typename first_type::size_type       size_type;
0642 
0643    public:
0644    segment_manager_iterator_value_adaptor(const typename Iterator::value_type &val)
0645       :  m_val(&val)
0646    {}
0647 
0648    const char_type *name() const
0649    {  return m_val->first.name(); }
0650 
0651    size_type name_length() const
0652    {  return m_val->first.name_length(); }
0653 
0654    const void *value() const
0655    {
0656       return move_detail::force_ptr<block_header<size_type>*>
0657          (to_raw_pointer(m_val->second.m_ptr))->value();
0658    }
0659 
0660    const typename Iterator::value_type *m_val;
0661 };
0662 
0663 template<class Iterator, bool intrusive>
0664 struct segment_manager_iterator_transform
0665 {
0666    typedef segment_manager_iterator_value_adaptor<Iterator, intrusive> result_type;
0667 
0668    template <class T> result_type operator()(const T &arg) const
0669    {  return result_type(arg); }
0670 };
0671 
0672 
0673 template<class T>
0674 inline T* null_or_bad_alloc(bool dothrow)
0675 {
0676    if (dothrow)
0677       throw bad_alloc();
0678    return 0;
0679 }
0680 
0681 template<class T>
0682 inline T* null_or_already_exists(bool dothrow)
0683 {
0684    if (dothrow)
0685       throw interprocess_exception(already_exists_error);
0686    return 0;
0687 }
0688 
0689 }  //namespace ipcdetail {
0690 
0691 //These pointers are the ones the user will use to
0692 //indicate previous allocation types
0693 static const ipcdetail::anonymous_instance_t   * anonymous_instance = 0;
0694 static const ipcdetail::unique_instance_t      * unique_instance = 0;
0695 
0696 namespace ipcdetail_really_deep_namespace {
0697 
0698 //Otherwise, gcc issues a warning of previously defined
0699 //anonymous_instance and unique_instance
0700 struct dummy
0701 {
0702    dummy()
0703    {
0704       (void)anonymous_instance;
0705       (void)unique_instance;
0706    }
0707 };
0708 
0709 }  //detail_really_deep_namespace
0710 
0711 }} //namespace boost { namespace interprocess
0712 
0713 #include <boost/interprocess/detail/config_end.hpp>
0714 
0715 #endif //#ifndef BOOST_INTERPROCESS_SEGMENT_MANAGER_BASE_HPP
0716