214 lines
4.0 KiB
C++
214 lines
4.0 KiB
C++
|
/*
|
||
|
*
|
||
|
* 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
|
||
|
|