blob: 443c57a25b9ad2291b42f2ab00e49f922f89d9d1 [file] [log] [blame]
/*
*
* Copyright (c) 1998-2002
* 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_raw_buffer.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Raw character buffer for regex code.
* Note this is an internal header file included
* by regex.hpp, do not include on its own.
*/
#ifndef BOOST_REGEX_RAW_BUFFER_HPP
#define BOOST_REGEX_RAW_BUFFER_HPP
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#include <algorithm>
#include <cstddef>
namespace boost{
namespace BOOST_REGEX_DETAIL_NS{
struct empty_padding{};
union padding
{
void* p;
unsigned int i;
};
template <int N>
struct padding3
{
enum{
padding_size = 8,
padding_mask = 7
};
};
template<>
struct padding3<2>
{
enum{
padding_size = 2,
padding_mask = 1
};
};
template<>
struct padding3<4>
{
enum{
padding_size = 4,
padding_mask = 3
};
};
template<>
struct padding3<8>
{
enum{
padding_size = 8,
padding_mask = 7
};
};
template<>
struct padding3<16>
{
enum{
padding_size = 16,
padding_mask = 15
};
};
enum{
padding_size = padding3<sizeof(padding)>::padding_size,
padding_mask = padding3<sizeof(padding)>::padding_mask
};
//
// class raw_storage
// basically this is a simplified vector<unsigned char>
// this is used by basic_regex for expression storage
//
class raw_storage
{
public:
typedef std::size_t size_type;
typedef unsigned char* pointer;
private:
pointer last, start, end;
public:
raw_storage();
raw_storage(size_type n);
~raw_storage()
{
::operator delete(start);
}
void resize(size_type n)
{
size_type newsize = start ? last - start : 1024;
while (newsize < n)
newsize *= 2;
size_type datasize = end - start;
// extend newsize to WORD/DWORD boundary:
newsize = (newsize + padding_mask) & ~(padding_mask);
// allocate and copy data:
pointer ptr = static_cast<pointer>(::operator new(newsize));
BOOST_REGEX_NOEH_ASSERT(ptr)
if (start)
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* extend(size_type n)
{
if(size_type(last - end) < n)
resize(n + (end - start));
pointer result = end;
end += n;
return result;
}
void* insert(size_type pos, size_type n)
{
BOOST_REGEX_ASSERT(pos <= size_type(end - start));
if (size_type(last - end) < n)
resize(n + (end - start));
void* result = start + pos;
std::memmove(start + pos + n, start + pos, (end - start) - pos);
end += n;
return result;
}
size_type size()
{
return size_type(end - start);
}
size_type capacity()
{
return size_type(last - start);
}
void* data()const
{
return start;
}
size_type index(void* ptr)
{
return size_type(static_cast<pointer>(ptr) - static_cast<pointer>(data()));
}
void clear()
{
end = start;
}
void align()
{
// move end up to a boundary:
end = start + (((end - start) + padding_mask) & ~padding_mask);
}
void swap(raw_storage& that)
{
std::swap(start, that.start);
std::swap(end, that.end);
std::swap(last, that.last);
}
};
inline raw_storage::raw_storage()
{
last = start = end = 0;
}
inline raw_storage::raw_storage(size_type n)
{
start = end = static_cast<pointer>(::operator new(n));
BOOST_REGEX_NOEH_ASSERT(start)
last = start + n;
}
} // namespace BOOST_REGEX_DETAIL_NS
} // namespace boost
#endif