#ifndef BOOST_RANGE_ATL_HPP | |
#define BOOST_RANGE_ATL_HPP | |
// Boost.Range ATL Extension | |
// | |
// Copyright Shunsuke Sogame 2005-2006. | |
// Distributed under the Boost Software License, Version 1.0. | |
// (See accompanying file LICENSE_1_0.txt or copy at | |
// http://www.boost.org/LICENSE_1_0.txt) | |
// config | |
// | |
#include <atldef.h> // _ATL_VER | |
#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) | |
#if (_ATL_VER < 0x0700) | |
#define BOOST_RANGE_ATL_NO_COLLECTIONS | |
#endif | |
#endif | |
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) | |
#if (_ATL_VER < 0x0700) // dubious | |
#define BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX | |
#endif | |
#endif | |
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING) | |
#if (_MSC_VER < 1310) // from <boost/regex/mfc.hpp>, but dubious | |
#define BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING | |
#endif | |
#endif | |
// forward declarations | |
// | |
#include <basetyps.h> // IID | |
namespace ATL { | |
#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) | |
// arrays | |
// | |
template< class E, class ETraits > | |
class CAtlArray; | |
template< class E > | |
class CAutoPtrArray; | |
template< class I, const IID *piid > | |
class CInterfaceArray; | |
// lists | |
// | |
template< class E, class ETraits > | |
class CAtlList; | |
template< class E > | |
class CAutoPtrList; | |
template< class E, class Allocator > | |
class CHeapPtrList; | |
template< class I, const IID *piid > | |
class CInterfaceList; | |
// maps | |
// | |
template< class K, class V, class KTraits, class VTraits > | |
class CAtlMap; | |
template< class K, class V, class KTraits, class VTraits > | |
class CRBTree; | |
template< class K, class V, class KTraits, class VTraits > | |
class CRBMap; | |
template< class K, class V, class KTraits, class VTraits > | |
class CRBMultiMap; | |
// strings | |
// | |
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING) | |
template< class BaseType, bool t_bMFCDLL > | |
class CSimpleStringT; | |
#else | |
template< class BaseType > | |
class CSimpleStringT; | |
#endif | |
template< class BaseType, class StringTraits > | |
class CStringT; | |
template< class StringType, int t_nChars > | |
class CFixedStringT; | |
template< class BaseType, const int t_nSize > | |
class CStaticString; | |
#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) | |
// simples | |
// | |
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) | |
template< class T, class TEqual > | |
class CSimpleArray; | |
template< class TKey, class TVal, class TEqual > | |
class CSimpleMap; | |
#else | |
template< class T > | |
class CSimpleArray; | |
template< class T > | |
class CSimpleValArray; | |
template< class TKey, class TVal > | |
class CSimpleMap; | |
#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) | |
// pointers | |
// | |
template< class E > | |
class CAutoPtr; | |
template< class T > | |
class CComPtr; | |
template< class T, const IID *piid > | |
class CComQIPtr; | |
template< class E, class Allocator > | |
class CHeapPtr; | |
template< class T > | |
class CAdapt; | |
} // namespace ATL | |
// indirect_iterator customizations | |
// | |
#include <boost/mpl/identity.hpp> | |
#include <boost/pointee.hpp> | |
namespace boost { | |
template< class E > | |
struct pointee< ATL::CAutoPtr<E> > : | |
mpl::identity<E> | |
{ }; | |
template< class T > | |
struct pointee< ATL::CComPtr<T> > : | |
mpl::identity<T> | |
{ }; | |
template< class T, const IID *piid > | |
struct pointee< ATL::CComQIPtr<T, piid> > : | |
mpl::identity<T> | |
{ }; | |
template< class E, class Allocator > | |
struct pointee< ATL::CHeapPtr<E, Allocator> > : | |
mpl::identity<E> | |
{ }; | |
template< class T > | |
struct pointee< ATL::CAdapt<T> > : | |
pointee<T> | |
{ }; | |
} // namespace boost | |
// extended customizations | |
// | |
#include <boost/iterator/indirect_iterator.hpp> | |
#include <boost/iterator/zip_iterator.hpp> | |
#include <boost/range/detail/microsoft.hpp> | |
#include <boost/tuple/tuple.hpp> | |
#include <atlbase.h> // CComBSTR | |
namespace boost { namespace range_detail_microsoft { | |
#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) | |
// arrays | |
// | |
struct atl_array_functions : | |
array_functions | |
{ | |
template< class Iterator, class X > | |
Iterator end(X& x) // redefine | |
{ | |
return x.GetData() + x.GetCount(); // no 'GetSize()' | |
} | |
}; | |
template< class E, class ETraits > | |
struct customization< ATL::CAtlArray<E, ETraits> > : | |
atl_array_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef E val_t; | |
typedef val_t *mutable_iterator; | |
typedef val_t const *const_iterator; | |
}; | |
}; | |
template< class E > | |
struct customization< ATL::CAutoPtrArray<E> > : | |
atl_array_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
// ATL::CAutoPtr/CHeapPtr is no assignable. | |
typedef ATL::CAutoPtr<E> val_t; | |
typedef val_t *miter_t; | |
typedef val_t const *citer_t; | |
typedef indirect_iterator<miter_t> mutable_iterator; | |
typedef indirect_iterator<citer_t> const_iterator; | |
}; | |
}; | |
template< class I, const IID *piid > | |
struct customization< ATL::CInterfaceArray<I, piid> > : | |
atl_array_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef ATL::CComQIPtr<I, piid> val_t; | |
typedef val_t *mutable_iterator; | |
typedef val_t const *const_iterator; | |
}; | |
}; | |
template< class E, class ETraits > | |
struct customization< ATL::CAtlList<E, ETraits> > : | |
list_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef E val_t; | |
typedef list_iterator<X, val_t> mutable_iterator; | |
typedef list_iterator<X const, val_t const> const_iterator; | |
}; | |
}; | |
struct indirected_list_functions | |
{ | |
template< class Iterator, class X > | |
Iterator begin(X& x) | |
{ | |
typedef typename Iterator::base_type base_t; // == list_iterator | |
return Iterator(base_t(x, x.GetHeadPosition())); | |
} | |
template< class Iterator, class X > | |
Iterator end(X& x) | |
{ | |
typedef typename Iterator::base_type base_t; | |
return Iterator(base_t(x, POSITION(0))); | |
} | |
}; | |
template< class E > | |
struct customization< ATL::CAutoPtrList<E> > : | |
indirected_list_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef ATL::CAutoPtr<E> val_t; | |
typedef list_iterator<X, val_t> miter_t; | |
typedef list_iterator<X const, val_t const> citer_t; | |
typedef indirect_iterator<miter_t> mutable_iterator; | |
typedef indirect_iterator<citer_t> const_iterator; | |
}; | |
}; | |
template< class E, class Allocator > | |
struct customization< ATL::CHeapPtrList<E, Allocator> > : | |
indirected_list_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef ATL::CHeapPtr<E, Allocator> val_t; | |
typedef list_iterator<X, val_t> miter_t; | |
typedef list_iterator<X const, val_t const> citer_t; | |
typedef indirect_iterator<miter_t> mutable_iterator; | |
typedef indirect_iterator<citer_t> const_iterator; | |
}; | |
}; | |
template< class I, const IID *piid > | |
struct customization< ATL::CInterfaceList<I, piid> > : | |
list_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef ATL::CComQIPtr<I, piid> val_t; | |
typedef list_iterator<X, val_t> mutable_iterator; | |
typedef list_iterator<X const, val_t const> const_iterator; | |
}; | |
}; | |
// maps | |
// | |
struct atl_rb_tree_tag | |
{ }; | |
template< > | |
struct customization< atl_rb_tree_tag > : | |
indirected_list_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef typename X::CPair val_t; | |
typedef list_iterator<X, val_t *, val_t *> miter_t; | |
typedef list_iterator<X const, val_t const *, val_t const *> citer_t; | |
typedef indirect_iterator<miter_t> mutable_iterator; | |
typedef indirect_iterator<citer_t> const_iterator; | |
}; | |
}; | |
template< class K, class V, class KTraits, class VTraits > | |
struct customization< ATL::CAtlMap<K, V, KTraits, VTraits> > : | |
customization< atl_rb_tree_tag > | |
{ | |
template< class Iterator, class X > | |
Iterator begin(X& x) // redefine | |
{ | |
typedef typename Iterator::base_type base_t; // == list_iterator | |
return Iterator(base_t(x, x.GetStartPosition())); // no 'GetHeadPosition' | |
} | |
}; | |
// strings | |
// | |
struct atl_string_tag | |
{ }; | |
template< > | |
struct customization< atl_string_tag > | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef typename X::PXSTR mutable_iterator; | |
typedef typename X::PCXSTR const_iterator; | |
}; | |
template< class Iterator, class X > | |
typename mutable_<Iterator, X>::type begin(X& x) | |
{ | |
return x.GetBuffer(0); | |
} | |
template< class Iterator, class X > | |
Iterator begin(X const& x) | |
{ | |
return x.GetString(); | |
} | |
template< class Iterator, class X > | |
Iterator end(X& x) | |
{ | |
return begin<Iterator>(x) + x.GetLength(); | |
} | |
}; | |
template< class BaseType, const int t_nSize > | |
struct customization< ATL::CStaticString<BaseType, t_nSize> > | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef BaseType const *mutable_iterator; | |
typedef mutable_iterator const_iterator; | |
}; | |
template< class Iterator, class X > | |
Iterator begin(X const& x) | |
{ | |
return x; | |
} | |
template< class Iterator, class X > | |
Iterator end(X const& x) | |
{ | |
return begin<Iterator>(x) + X::GetLength(); | |
} | |
}; | |
#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) | |
template< > | |
struct customization< ATL::CComBSTR > | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef OLECHAR *mutable_iterator; | |
typedef OLECHAR const *const_iterator; | |
}; | |
template< class Iterator, class X > | |
Iterator begin(X& x) | |
{ | |
return x.operator BSTR(); | |
} | |
template< class Iterator, class X > | |
Iterator end(X& x) | |
{ | |
return begin<Iterator>(x) + x.Length(); | |
} | |
}; | |
// simples | |
// | |
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) | |
template< class T, class TEqual > | |
struct customization< ATL::CSimpleArray<T, TEqual> > : | |
#else | |
template< class T > | |
struct customization< ATL::CSimpleArray<T> > : | |
#endif | |
array_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef T val_t; | |
typedef val_t *mutable_iterator; | |
typedef val_t const *const_iterator; | |
}; | |
}; | |
#if defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) | |
template< class T > | |
struct customization< ATL::CSimpleValArray<T> > : | |
array_functions | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef T val_t; | |
typedef val_t *mutable_iterator; | |
typedef val_t const *const_iterator; | |
}; | |
}; | |
#endif // defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) | |
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) | |
template< class TKey, class TVal, class TEqual > | |
struct customization< ATL::CSimpleMap<TKey, TVal, TEqual> > | |
#else | |
template< class TKey, class TVal > | |
struct customization< ATL::CSimpleMap<TKey, TVal> > | |
#endif | |
{ | |
template< class X > | |
struct meta | |
{ | |
typedef TKey k_val_t; | |
typedef k_val_t *k_miter_t; | |
typedef k_val_t const *k_citer_t; | |
typedef TVal v_val_t; | |
typedef v_val_t *v_miter_t; | |
typedef v_val_t const *v_citer_t; | |
// Topic: | |
// 'std::pair' can't contain references | |
// because of reference to reference problem. | |
typedef zip_iterator< tuple<k_miter_t, v_miter_t> > mutable_iterator; | |
typedef zip_iterator< tuple<k_citer_t, v_citer_t> > const_iterator; | |
}; | |
template< class Iterator, class X > | |
Iterator begin(X& x) | |
{ | |
return Iterator(boost::make_tuple(x.m_aKey, x.m_aVal)); | |
} | |
template< class Iterator, class X > | |
Iterator end(X& x) | |
{ | |
return Iterator(boost::make_tuple(x.m_aKey + x.GetSize(), x.m_aVal + x.GetSize())); | |
} | |
}; | |
} } // namespace boost::range_detail_microsoft | |
// range customizations | |
// | |
#if !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) | |
// arrays | |
// | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CAtlArray, 2 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CAutoPtrArray, 1 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CInterfaceArray, (class)(const IID *) | |
) | |
// lists | |
// | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CAtlList, 2 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CAutoPtrList, 1 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CHeapPtrList, 2 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CInterfaceList, (class)(const IID *) | |
) | |
//maps | |
// | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CAtlMap, 4 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::atl_rb_tree_tag, | |
(ATL, BOOST_PP_NIL), CRBTree, 4 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::atl_rb_tree_tag, | |
(ATL, BOOST_PP_NIL), CRBMap, 4 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::atl_rb_tree_tag, | |
(ATL, BOOST_PP_NIL), CRBMultiMap, 4 | |
) | |
// strings | |
// | |
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLESTRING) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::atl_string_tag, | |
(ATL, BOOST_PP_NIL), CSimpleStringT, (class)(bool) | |
) | |
#else | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::atl_string_tag, | |
(ATL, BOOST_PP_NIL), CSimpleStringT, 1 | |
) | |
#endif | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::atl_string_tag, | |
(ATL, BOOST_PP_NIL), CStringT, 2 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::atl_string_tag, | |
(ATL, BOOST_PP_NIL), CFixedStringT, (class)(int) | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CStaticString, (class)(const int) | |
) | |
#endif // !defined(BOOST_RANGE_ATL_NO_COLLECTIONS) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TYPE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CComBSTR | |
) | |
// simples | |
// | |
#if !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CSimpleArray, 2 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CSimpleMap, 3 | |
) | |
#else | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CSimpleArray, 1 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CSimpleMap, 2 | |
) | |
BOOST_RANGE_DETAIL_MICROSOFT_CUSTOMIZATION_TEMPLATE( | |
boost::range_detail_microsoft::using_type_as_tag, | |
(ATL, BOOST_PP_NIL), CSimpleValArray, 1 | |
) | |
#endif // !defined(BOOST_RANGE_ATL_HAS_OLD_CSIMPLE_XXX) | |
#endif |