Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-14 08:35:24

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