Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r66610 - in sandbox/regex-allocator: boost/regex boost/regex/v4 libs/regex/src
From: john_at_[hidden]
Date: 2010-11-16 04:17:16


Author: johnmaddock
Date: 2010-11-16 04:17:12 EST (Tue, 16 Nov 2010)
New Revision: 66610
URL: http://svn.boost.org/trac/boost/changeset/66610

Log:
First draft of allocator-aware basic_regex.
Added:
   sandbox/regex-allocator/boost/regex/v4/allocator_support.hpp (contents, props changed)
Text files modified:
   sandbox/regex-allocator/boost/regex/concepts.hpp | 45 +++++++++++++++++++++
   sandbox/regex-allocator/boost/regex/v4/basic_regex.hpp | 82 ++++++++++++++++++++++++---------------
   sandbox/regex-allocator/boost/regex/v4/regex_raw_buffer.hpp | 60 +++++++++++++++++++++++++---
   sandbox/regex-allocator/libs/regex/src/regex_raw_buffer.cpp | 34 ----------------
   4 files changed, 147 insertions(+), 74 deletions(-)

Modified: sandbox/regex-allocator/boost/regex/concepts.hpp
==============================================================================
--- sandbox/regex-allocator/boost/regex/concepts.hpp (original)
+++ sandbox/regex-allocator/boost/regex/concepts.hpp 2010-11-16 04:17:12 EST (Tue, 16 Nov 2010)
@@ -159,6 +159,36 @@
 template <class T>
 bool operator != (const allocator_architype_2<T>&, const allocator_architype_2<T>&);
 
+template <>
+class allocator_architype_2<void>
+{
+public:
+ typedef void* pointer;
+ typedef const void* const_pointer;
+ typedef void value_type;
+ typedef unsigned size_type;
+ typedef int difference_type;
+
+ template <class U>
+ struct rebind
+ {
+ typedef allocator_architype_2<U> other;
+ };
+
+ pointer allocate(size_type);
+ pointer allocate(size_type, pointer);
+ void deallocate(pointer, size_type);
+ size_type max_size()const;
+
+ allocator_architype_2();
+ allocator_architype_2(const allocator_architype_2&);
+
+ template <class Other>
+ allocator_architype_2(const allocator_architype_2<Other>&);
+
+ void destroy(pointer);
+};
+
 namespace boost{
 //
 // regex_traits_architype:
@@ -654,6 +684,7 @@
    typedef global_regex_namespace::sub_match<BidiIterator> sub_match_type;
    typedef global_regex_namespace::match_results<BidiIterator, allocator_architype<sub_match_type> > match_results_type;
    typedef output_iterator_archetype<value_type> OutIterator;
+ typedef input_iterator_archetype<value_type> input_iterator_type;
 
 
    void constraints()
@@ -665,6 +696,18 @@
       Regex e2(m_string, m_flags);
       ignore_unused_variable_warning(e2);
 
+ // Allocator based construction:
+ typedef typename Regex::allocator_type regex_alloc;
+ regex_alloc a;
+ Regex e3(a);
+ ignore_unused_variable_warning(e3);
+ Regex e5(m_pointer, m_flags, a);
+ ignore_unused_variable_warning(e5);
+ Regex e6(m_pointer, m_size, m_flags, a);
+ ignore_unused_variable_warning(e6);
+ Regex e8(in1, in2, m_flags, a);
+ ignore_unused_variable_warning(e8);
+
       // assign etc:
       Regex e;
       e = m_string;
@@ -826,6 +869,8 @@
    const match_results_type m_cresults;
    OutIterator m_out;
    BidiIterator m_in;
+ std::size_t m_size;
+ input_iterator_type in1, in2;
    global_regex_namespace::regex_constants::match_flag_type m_mft;
    global_regex_namespace::match_results<typename string_type::const_iterator, allocator_architype<global_regex_namespace::sub_match<typename string_type::const_iterator> > > m_smatch;
 

Added: sandbox/regex-allocator/boost/regex/v4/allocator_support.hpp
==============================================================================
--- (empty file)
+++ sandbox/regex-allocator/boost/regex/v4/allocator_support.hpp 2010-11-16 04:17:12 EST (Tue, 16 Nov 2010)
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright (c) 2010
+ * John Maddock
+ *
+ * Use, modification and distribution are subject to 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)
+ *
+ */
+
+#ifndef BOOST_REGEX_ALLOCATOR_SUPPORT
+#define BOOST_REGEX_ALLOCATOR_SUPPORT
+
+#include <memory>
+#include <new>
+
+namespace boost{ namespace re_detail{
+
+template <class Allocator>
+struct allocator_deleter : public Allocator
+{
+ allocator_deleter(const Allocator& a) : Allocator(a){}
+
+ template <class T>
+ void operator()(T* p)
+ {
+ this->destroy(p);
+ this->deallocate(p, 1);
+ }
+};
+
+template <class T, class Allocator>
+shared_ptr<T> create_shared_ptr(const Allocator& a1)
+{
+ typedef typename Allocator::template rebind<T> bound_type;
+ typedef typename bound_type::other alloc_type;
+
+ alloc_type a(a1);
+ T* p = a.allocate(1);
+ try{
+ new (p) T();
+ }
+ catch(...)
+ {
+ a.destroy(p);
+ throw;
+ }
+ return shared_ptr<T>(p, allocator_deleter<alloc_type>(a), a1);
+}
+
+template <class T, class Arg1, class Allocator>
+shared_ptr<T> create_shared_ptr(const Arg1& arg1, const Allocator& a1)
+{
+ typedef typename Allocator::template rebind<T> bound_type;
+ typedef typename bound_type::other alloc_type;
+
+ alloc_type a(a1);
+ T* p = a.allocate(1);
+ try{
+ new (p) T(arg1);
+ }
+ catch(...)
+ {
+ a.destroy(p);
+ throw;
+ }
+ return shared_ptr<T>(p, allocator_deleter<alloc_type>(a), a1);
+}
+
+template <class T, class Arg1, class Arg2, class Allocator>
+shared_ptr<T> create_shared_ptr(const Arg1& arg1, const Arg2 arg2, const Allocator& a1)
+{
+ typedef typename Allocator::template rebind<T> bound_type;
+ typedef typename bound_type::other alloc_type;
+
+ alloc_type a(a1);
+ T* p = a.allocate(1);
+ try{
+ new (p) T(arg1, arg2);
+ }
+ catch(...)
+ {
+ a.destroy(p);
+ throw;
+ }
+ return shared_ptr<T>(p, allocator_deleter<alloc_type>(a), a1);
+}
+
+}} // namespaces
+
+#endif // BOOST_REGEX_ALLOCATOR_SUPPORT

Modified: sandbox/regex-allocator/boost/regex/v4/basic_regex.hpp
==============================================================================
--- sandbox/regex-allocator/boost/regex/v4/basic_regex.hpp (original)
+++ sandbox/regex-allocator/boost/regex/v4/basic_regex.hpp 2010-11-16 04:17:12 EST (Tue, 16 Nov 2010)
@@ -21,6 +21,7 @@
 
 #include <boost/type_traits/is_same.hpp>
 #include <boost/functional/hash.hpp>
+#include <boost/regex/v4/allocator_support.hpp>
 
 #ifdef BOOST_MSVC
 #pragma warning(push)
@@ -105,7 +106,7 @@
    typedef std::vector<name>::const_iterator const_iterator;
    typedef std::pair<const_iterator, const_iterator> range_type;
 
- named_subexpressions(){}
+ named_subexpressions() {}
 
    template <class charT>
    void set_name(const charT* i, const charT* j, int index)
@@ -154,16 +155,16 @@
 // represents the data we wish to expose to the matching algorithms.
 //
 template <class charT, class traits, class Allocator>
-struct regex_data : public named_subexpressions
+struct regex_data : public named_subexpressions, public Allocator
 {
    typedef regex_constants::syntax_option_type flag_type;
    typedef std::size_t size_type;
 
    regex_data(const ::boost::shared_ptr<
- ::boost::regex_traits_wrapper<traits> >& t)
- : m_ptraits(t), m_expression(0), m_expression_len(0) {}
- regex_data()
- : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_expression(0), m_expression_len(0) {}
+ ::boost::regex_traits_wrapper<traits> >& t, const Allocator& a)
+ : Allocator(a), m_ptraits(t), m_expression(0), m_expression_len(0), m_data(a), m_subs(a) {}
+ regex_data(const Allocator& a)
+ : Allocator(a), m_ptraits(create_shared_ptr< ::boost::regex_traits_wrapper<traits> >(a)), m_expression(0), m_expression_len(0), m_data(a), m_subs(a) {}
 
    ::boost::shared_ptr<
       ::boost::regex_traits_wrapper<traits>
@@ -177,12 +178,17 @@
    unsigned m_restart_type; // search optimisation type
    unsigned char m_startmap[1 << CHAR_BIT]; // which characters can start a match
    unsigned int m_can_be_null; // whether we can match a null string
- re_detail::raw_storage m_data; // the buffer in which our states are constructed
+ re_detail::raw_storage<Allocator> m_data; // the buffer in which our states are constructed
    typename traits::char_class_type m_word_mask; // mask used to determine if a character is a word character
    std::vector<
       std::pair<
- std::size_t, std::size_t> > m_subs; // Position of sub-expressions within the *string*.
+ std::size_t, std::size_t>, Allocator> m_subs; // Position of sub-expressions within the *string*.
    bool m_has_recursions; // whether we have recursive expressions;
+
+ const Allocator& get_allocator()const
+ {
+ return *this;
+ }
 };
 //
 // class basic_regex_implementation
@@ -199,10 +205,10 @@
    typedef typename traits::locale_type locale_type;
    typedef const charT* const_iterator;
 
- basic_regex_implementation(){}
+ basic_regex_implementation(const Allocator& a) : regex_data<charT, traits, Allocator>(a) {}
    basic_regex_implementation(const ::boost::shared_ptr<
- ::boost::regex_traits_wrapper<traits> >& t)
- : regex_data<charT, traits, Allocator>(t) {}
+ ::boost::regex_traits_wrapper<traits> >& t, const Allocator& a)
+ : regex_data<charT, traits, Allocator>(t, a) {}
    void assign(const charT* arg_first,
                           const charT* arg_last,
                           flag_type f)
@@ -326,20 +332,28 @@
    // traits class to localise *this.
    typedef typename traits::locale_type locale_type;
    typedef Allocator allocator_type;
+
+private:
+ typedef typename Allocator::template rebind<unsigned char> rebind_type;
+ typedef typename rebind_type::other forwarding_allocator;
    
 public:
    explicit basic_regex(){}
- explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
+ explicit basic_regex(const Allocator& a)
    {
- assign(p, f);
+ m_pimpl = re_detail::create_shared_ptr<re_detail::basic_regex_implementation<charT, traits, forwarding_allocator> >(forwarding_allocator(a), a);
    }
- basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
+ explicit basic_regex(const charT* p, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
    {
- assign(p1, p2, f);
+ do_assign(p, p + traits::length(p), f, &a);
    }
- basic_regex(const charT* p, size_type len, flag_type f)
+ basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
    {
- assign(p, len, f);
+ do_assign(p1, p2, f, &a);
+ }
+ basic_regex(const charT* p, size_type len, flag_type f, const Allocator& a = Allocator())
+ {
+ do_assign(p, p + len, f, &a);
    }
    basic_regex(const basic_regex& that)
       : m_pimpl(that.m_pimpl) {}
@@ -371,7 +385,8 @@
 private:
    basic_regex& do_assign(const charT* p1,
                           const charT* p2,
- flag_type f);
+ flag_type f,
+ const Allocator* pa = 0);
 public:
    basic_regex& assign(const charT* p1,
                           const charT* p2,
@@ -388,20 +403,20 @@
    }
 
    template <class ST, class SA>
- explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
+ explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
    {
- assign(p, f);
+ do_assign(p.c_str(), p.c_str() + p.size(), f, &a);
    }
 
    template <class InputIterator>
- basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
+ basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
    {
       typedef typename traits::string_type seq_type;
- seq_type a(arg_first, arg_last);
- if(a.size())
- assign(&*a.begin(), &*a.begin() + a.size(), f);
+ seq_type t(arg_first, arg_last);
+ if(t.size())
+ do_assign(&*t.begin(), &*t.begin() + t.size(), f, &a);
       else
- assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
+ do_assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f, &a);
    }
 
    template <class ST, class SA>
@@ -622,7 +637,7 @@
       BOOST_ASSERT(0 != m_pimpl.get());
       return m_pimpl->can_be_null();
    }
- const re_detail::regex_data<charT, traits, Allocator>& get_data()const
+ const re_detail::regex_data<charT, traits, forwarding_allocator>& get_data()const
    {
       BOOST_ASSERT(0 != m_pimpl.get());
       return m_pimpl->get_data();
@@ -633,7 +648,7 @@
    }
 
 private:
- shared_ptr<re_detail::basic_regex_implementation<charT, traits, Allocator> > m_pimpl;
+ shared_ptr<re_detail::basic_regex_implementation<charT, traits, forwarding_allocator> > m_pimpl;
 };
 
 //
@@ -645,16 +660,18 @@
 template <class charT, class traits, class Allocator>
 basic_regex<charT, traits, Allocator>& basic_regex<charT, traits, Allocator>::do_assign(const charT* p1,
                         const charT* p2,
- flag_type f)
+ flag_type f,
+ const Allocator* pa)
 {
- shared_ptr<re_detail::basic_regex_implementation<charT, traits, Allocator> > temp;
+ shared_ptr<re_detail::basic_regex_implementation<charT, traits, forwarding_allocator> > temp;
+ Allocator a = pa ? *pa : m_pimpl.get() ? Allocator(m_pimpl->get_allocator()) : Allocator();
    if(!m_pimpl.get())
    {
- temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits, Allocator> >(new re_detail::basic_regex_implementation<charT, traits, Allocator>());
+ temp = re_detail::create_shared_ptr<re_detail::basic_regex_implementation<charT, traits, forwarding_allocator> >(forwarding_allocator(a), a);
    }
    else
    {
- temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits, Allocator> >(new re_detail::basic_regex_implementation<charT, traits, Allocator>(m_pimpl->m_ptraits));
+ temp = re_detail::create_shared_ptr<re_detail::basic_regex_implementation<charT, traits, forwarding_allocator> >(m_pimpl->m_ptraits, forwarding_allocator(a), a);
    }
    temp->assign(p1, p2, f);
    temp.swap(m_pimpl);
@@ -664,7 +681,8 @@
 template <class charT, class traits, class Allocator>
 typename basic_regex<charT, traits, Allocator>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits, Allocator>::imbue(locale_type l)
 {
- shared_ptr<re_detail::basic_regex_implementation<charT, traits, Allocator> > temp(new re_detail::basic_regex_implementation<charT, traits, Allocator>());
+ Allocator a(m_pimpl.get() ? Allocator(m_pimpl->get_allocator()) : Allocator());
+ shared_ptr<re_detail::basic_regex_implementation<charT, traits, forwarding_allocator> > temp(re_detail::create_shared_ptr<re_detail::basic_regex_implementation<charT, traits, forwarding_allocator> >(forwarding_allocator(a), a));
    locale_type result = temp->imbue(l);
    temp.swap(m_pimpl);
    return result;

Modified: sandbox/regex-allocator/boost/regex/v4/regex_raw_buffer.hpp
==============================================================================
--- sandbox/regex-allocator/boost/regex/v4/regex_raw_buffer.hpp (original)
+++ sandbox/regex-allocator/boost/regex/v4/regex_raw_buffer.hpp 2010-11-16 04:17:12 EST (Tue, 16 Nov 2010)
@@ -105,22 +105,25 @@
 // basically this is a simplified vector<unsigned char>
 // this is used by basic_regex for expression storage
 //
-
-class BOOST_REGEX_DECL raw_storage
+template <class Allocator>
+class BOOST_REGEX_DECL raw_storage : public Allocator
 {
 public:
    typedef std::size_t size_type;
    typedef unsigned char* pointer;
 private:
    pointer last, start, end;
+ typedef typename Allocator::template rebind<unsigned char> bound_type;
+ typedef typename bound_type::other byte_allocator;
 public:
 
- raw_storage();
- raw_storage(size_type n);
+ raw_storage(const Allocator& a);
+ raw_storage(size_type n, const Allocator& a);
 
    ~raw_storage()
    {
- ::operator delete(start);
+ byte_allocator a(*this);
+ a.deallocate(start, end - start);
    }
 
    void BOOST_REGEX_CALL resize(size_type n);
@@ -168,24 +171,65 @@
    }
    void swap(raw_storage& that)
    {
+ std::swap(static_cast<Allocator&>(*this), static_cast<Allocator&>(that));
       std::swap(start, that.start);
       std::swap(end, that.end);
       std::swap(last, that.last);
   }
 };
 
-inline raw_storage::raw_storage()
+template <class Allocator>
+inline raw_storage<Allocator>::raw_storage(const Allocator& a) : Allocator(a)
 {
    last = start = end = 0;
 }
 
-inline raw_storage::raw_storage(size_type n)
+template <class Allocator>
+inline raw_storage<Allocator>::raw_storage(size_type n, const Allocator& a1) : Allocator(a1)
 {
- start = end = static_cast<pointer>(::operator new(n));
+ byte_allocator a(a1);
+ start = end = a.allocate(n);
    BOOST_REGEX_NOEH_ASSERT(start)
    last = start + n;
 }
 
+template <class Allocator>
+void BOOST_REGEX_CALL raw_storage<Allocator>::resize(size_type n)
+{
+ byte_allocator a(*this);
+ register size_type newsize = start ? last - start : 1024;
+ while(newsize < n)
+ newsize *= 2;
+ register size_type datasize = end - start;
+ // extend newsize to WORD/DWORD boundary:
+ newsize = (newsize + padding_mask) & ~(padding_mask);
+
+ // allocate and copy data:
+ register pointer ptr = a.allocate(newsize);
+ BOOST_REGEX_NOEH_ASSERT(ptr)
+ std::memcpy(ptr, start, datasize);
+
+ // get rid of old buffer:
+ a.deallocate(start, last - start);
+
+ // and set up pointers:
+ start = ptr;
+ end = ptr + datasize;
+ last = ptr + newsize;
+}
+
+template <class Allocator>
+void* BOOST_REGEX_CALL raw_storage<Allocator>::insert(size_type pos, size_type n)
+{
+ BOOST_ASSERT(pos <= size_type(end - start));
+ if(size_type(last - end) < n)
+ resize(n + (end - start));
+ register void* result = start + pos;
+ std::memmove(start + pos + n, start + pos, (end - start) - pos);
+ end += n;
+ return result;
+}
+
 
 #ifdef BOOST_MSVC
 #pragma warning(push)

Modified: sandbox/regex-allocator/libs/regex/src/regex_raw_buffer.cpp
==============================================================================
--- sandbox/regex-allocator/libs/regex/src/regex_raw_buffer.cpp (original)
+++ sandbox/regex-allocator/libs/regex/src/regex_raw_buffer.cpp 2010-11-16 04:17:12 EST (Tue, 16 Nov 2010)
@@ -33,38 +33,4 @@
 
 namespace boost{ namespace re_detail{
 
-void BOOST_REGEX_CALL raw_storage::resize(size_type n)
-{
- register size_type newsize = start ? last - start : 1024;
- while(newsize < n)
- newsize *= 2;
- register size_type datasize = end - start;
- // extend newsize to WORD/DWORD boundary:
- newsize = (newsize + padding_mask) & ~(padding_mask);
-
- // allocate and copy data:
- register pointer ptr = static_cast<pointer>(::operator new(newsize));
- BOOST_REGEX_NOEH_ASSERT(ptr)
- std::memcpy(ptr, start, datasize);
-
- // get rid of old buffer:
- ::operator delete(start);
-
- // and set up pointers:
- start = ptr;
- end = ptr + datasize;
- last = ptr + newsize;
-}
-
-void* BOOST_REGEX_CALL raw_storage::insert(size_type pos, size_type n)
-{
- BOOST_ASSERT(pos <= size_type(end - start));
- if(size_type(last - end) < n)
- resize(n + (end - start));
- register void* result = start + pos;
- std::memmove(start + pos + n, start + pos, (end - start) - pos);
- end += n;
- return result;
-}
-
 }} // namespaces


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk