#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