class CDeserialiser
{
- const size_t m_length;
- const uint8_t* m_data;
+ ::std::vector<uint8_t> m_vect;
size_t m_offset;
public:
- CDeserialiser(size_t Length, const uint8_t *Buffer);
+ CDeserialiser():
+ CDeserialiser(::std::vector<uint8_t>())
+ {}
+ CDeserialiser(const ::std::vector<uint8_t>& vect);
+ CDeserialiser(::std::vector<uint8_t>&& vect);
+ CDeserialiser(const CDeserialiser& x) { *this = x; };
+ CDeserialiser& operator=(const CDeserialiser& x);
bool IsConsumed() const;
::uint8_t ReadU8();
::uint16_t ReadU16();
namespace AxWin {
-CDeserialiser::CDeserialiser(size_t Length, const uint8_t *Buffer):
- m_length(Length),
- m_data(Buffer),
+CDeserialiser::CDeserialiser(const ::std::vector<uint8_t>& vector):
+ m_vect(vector),
m_offset(0)
{
}
+CDeserialiser::CDeserialiser(::std::vector<uint8_t>&& vector):
+ m_vect(vector),
+ m_offset(0)
+{
+}
+CDeserialiser& CDeserialiser::operator=(const CDeserialiser& x)
+{
+ m_vect = x.m_vect;
+ m_offset = x.m_offset;
+}
bool CDeserialiser::IsConsumed() const
{
- return m_offset == m_length;
+ return m_offset == m_vect.size();
}
::uint8_t CDeserialiser::ReadU8()
{
RangeCheck("CDeserialiser::ReadU8", 1);
- uint8_t rv = m_data[m_offset];
+ uint8_t rv = m_vect[m_offset];
m_offset ++;
return rv;
}
::uint16_t CDeserialiser::ReadU16()
{
RangeCheck("CDeserialiser::ReadU16", 2);
- uint16_t rv = m_data[m_offset] | ((uint16_t)m_data[m_offset+1] << 8);
+ uint16_t rv = m_vect[m_offset] | ((uint16_t)m_vect[m_offset+1] << 8);
m_offset += 2;
return rv;
}
RangeCheck("CDeserialiser::ReadBuffer(len)", 2);
size_t size = ReadU16();
- ::std::vector<uint8_t> ret( size );
- for( size_t i = 0; i < size; i ++ )
- ret[i] = m_data[m_offset++];
+ auto range_start = m_vect.begin() + int(m_offset);
+ ::std::vector<uint8_t> ret( range_start, range_start + int(size) );
+ m_offset += size;
return ret;
}
const ::std::string CDeserialiser::ReadString()
{
RangeCheck("CDeserialiser::ReadString(len)", 1);
- uint8_t len = m_data[m_offset];
- m_offset ++;
+ uint8_t len = ReadU8();
RangeCheck("CDeserialiser::ReadString(data)", len);
- ::std::string ret( reinterpret_cast<const char*>(m_data+m_offset), len );
+ ::std::string ret( reinterpret_cast<const char*>(m_vect.data()+m_offset), len );
m_offset += len;
return ret;
}
void CDeserialiser::RangeCheck(const char *Method, size_t bytes) throw(::std::out_of_range)
{
- if( m_offset + bytes > m_length ) {
- ::_SysDebug("%s - out of range %i+%i >= %i", Method, m_offset, bytes, m_length);
+ if( m_offset + bytes > m_vect.size() ) {
+ ::_SysDebug("%s - out of range %i+%i >= %i", Method, m_offset, bytes, m_vect.size());
throw ::std::out_of_range(Method);
}
}
CWindow* CClient::GetWindow(int ID)
{
- _SysDebug("GetWindow(ID=%i)", ID);
try {
return m_windows.at(ID);
}
CClient_AcessIPCPipe::CClient_AcessIPCPipe(::AxWin::IIPCChannel& channel, int fd):
CClient(channel),
- m_fd(fd),
- m_rxbuf(0x1000)
+ m_fd(fd)
{
}
const ::std::vector<uint8_t>& data = message.Compact();
_SysDebug("CClient_AcessIPCPipe::SendMessage - %i bytes to %i", data.size(), m_fd);
+ _SysDebugHex("CClient_AcessIPCPipe::SendMessage", data.data(), data.size());
_SysWrite(m_fd, data.data(), data.size());
}
void CClient_AcessIPCPipe::HandleReceive()
{
- size_t len = _SysRead(m_fd, &m_rxbuf[0], m_rxbuf.capacity());
+ ::std::vector<uint8_t> rxbuf(0x1000);
+ size_t len = _SysRead(m_fd, rxbuf.data(), rxbuf.capacity());
if( len == (size_t)-1 )
throw ::std::system_error(errno, ::std::system_category());
+ //_SysDebug("CClient_AcessIPCPipe::HandleReceive - Rx %i/%i bytes", len, rxbuf.capacity());
+ //_SysDebugHex("CClient_AcessIPCPipe::HandleReceive", m_rxbuf.data(), len);
+ rxbuf.resize(len);
- CDeserialiser message(len, &m_rxbuf[0]);
- CClient::HandleMessage(message);
+ CDeserialiser msg( ::std::move(rxbuf) );
+ CClient::HandleMessage( msg );
}
};
*/
#include <CRect.hpp>
#include <algorithm>
+#include <acess/sys.h>
namespace AxWin {
int x2 = ::std::min(m_x2, other.m_x2);
int y2 = ::std::min(m_y2, other.m_y2);
- if( x1 <= x2 || y2 <= y1 )
+ if( x2 <= x1 || y2 <= y1 )
return CRect();
- return CRect(x1, y1, x2-x1, y2-y2);
+ return CRect(x1, y1, x2-x1, y2-y1);
}
CRect CRect::RelativeIntersection(const CRect& area)
void CWindow::Show(bool bShow)
{
- assert(!"TODO: CWindow::Show");
+ if( m_is_shown == bShow )
+ return;
+
+ if( bShow )
+ m_compositor.ShowWindow( this );
+ else
+ m_compositor.HideWindow( this );
+ m_is_shown = bShow;
}
void CWindow::Move(int X, int Y)
{
}
+
+void CWindow::DrawScanline(unsigned int row, unsigned int x, unsigned int w, const uint8_t *data)
+{
+ m_surface.DrawScanline(row, x, w, data);
+ CRect damaged( m_surface.m_rect.m_x+x, m_surface.m_rect.m_y+row, w, 1 );
+ m_compositor.DamageArea(damaged);
+}
+
};
BIN := AxWinServer
LDFLAGS += -lc++
+CXXFLAGS += -O3
include ../../Makefile.tpl
return new CWindow(*this, client, name);
}
+void CCompositor::ShowWindow(CWindow* window)
+{
+ DamageArea(window->m_surface.m_rect);
+ // TODO: Append to separate sub-lists (or to separate lists all together)
+ // if flags AXWIN4_WNDFLAG_KEEPBELOW or AXWIN4_WNDFLAG_KEEPABOVE are set
+ m_windows.push_back(window);
+}
+void CCompositor::HideWindow(CWindow* window)
+{
+ DamageArea(window->m_surface.m_rect);
+ m_windows.remove(window);
+}
+
bool CCompositor::GetScreenDims(unsigned int ScreenID, unsigned int* W, unsigned int* H)
{
assert(W && H);
void CCompositor::Redraw()
{
- _SysDebug("CCompositor::Redraw");
// Redraw the screen and clear damage rects
- if( m_damageRects.empty() )
+ if( m_damageRects.empty() ) {
+ _SysDebug("- No damaged regions");
return ;
+ }
// Build up foreground grid (Rects and windows)
// - This should already be built (mutated on window move/resize/reorder)
// For all windows, check for intersection with damage rects
for( auto rect : m_damageRects )
{
- _SysDebug("rect=(%i,%i) %ix%i", rect.m_x, rect.m_y, rect.m_w, rect.m_h);
// window list should be sorted by draw order (lowest first)
for( auto window : m_windows )
{
- if( rect.HasIntersection( window->m_surface.m_rect ) )
+ if( window->m_is_shown && rect.HasIntersection( window->m_surface.m_rect ) )
{
// TODO: just reblit
CRect rel_rect = window->m_surface.m_rect.RelativeIntersection(rect);
+ //_SysDebug("Reblit (%i,%i) %ix%i", rel_rect.m_x, rel_rect.m_y, rel_rect.m_w, rel_rect.m_h);
BlitFromSurface( window->m_surface, rel_rect );
//window->Repaint( rel_rect );
}
::std::list<CWindow*> m_windows;
::std::vector<TWindowID> m_windowIDBuffer; // One 32-bit value per pixel
- //::std::vector<CPixel> m_frameBuffer; // Local copy of the framebuffer (needed?)
public:
CCompositor(CVideo& video);
CWindow* CreateWindow(CClient& client, const ::std::string& name);
+ void ShowWindow(CWindow* window);
+ void HideWindow(CWindow* window);
+
bool GetScreenDims(unsigned int ScrenID, unsigned int *Width, unsigned int *Height);
void Redraw();
{
friend class CIPCChannel_AcessIPCPipe;
int m_fd;
- ::std::vector<uint8_t> m_rxbuf;
public:
CClient_AcessIPCPipe(IIPCChannel& channel, int fd);
~CClient_AcessIPCPipe();
void MouseMove(int NewX, int NewY);
void KeyEvent(::uint32_t Scancode, const ::std::string &Translated, bool Down);
+ void DrawScanline(unsigned int row, unsigned int x, unsigned int w, const uint8_t *data);
+
+ bool m_is_shown;
CSurface m_surface;
private:
CCompositor& m_compositor;
int ret = 0;
for( const auto channel : glChannels )
{
- _SysDebug("IPC::FillSelect - channel=%p", channel);
assert(channel);
ret = ::std::max(ret, channel->FillSelect(rfds));
}
reply.WriteU16( (w <= UINT16_MAX ? w : UINT16_MAX) );
reply.WriteU16( (h <= UINT16_MAX ? h : UINT16_MAX) );
break; }
+ case IPC_GLOBATTR_MAXAREA:
+ assert(!"TODO: IPC_GLOBATTR_MAXAREA");
+ break;
default:
throw IPC::CClientFailure("Bad global attribute ID");
}
int16_t new_y = message.ReadS16();
win->Move(new_x, new_y);
break; }
+ case IPC_WINATTR_SHOW:
+ win->Show( message.ReadU8() != 0 );
+ break;
+ case IPC_WINATTR_FLAGS:
+ _SysDebug("TODO: IPC_WINATTR_FLAGS");
+ break;
+ case IPC_WINATTR_TITLE:
+ assert(!"TODO: IPC_WINATTR_TITLE");
+ break;
default:
_SysDebug("HandleMessage_SetWindowAttr - Bad attr %u", attr_id);
throw IPC::CClientFailure("Bad window attr");
for( unsigned int row = 0; row < h; row ++ )
{
const ::std::vector<uint8_t> scanline_data = message.ReadBuffer();
- _SysDebug("_PushData: Scanline %i: %i bytes", row, scanline_data.size());
if( scanline_data.size() != w * 4 ) {
_SysDebug("ERROR _PushData: Scanline buffer size mismatch (%i,%i)",
scanline_data.size(), w*4);
continue ;
}
- win->m_surface.DrawScanline(y+row, x, w, scanline_data.data());
+ win->DrawScanline(y+row, x, w, scanline_data.data());
}
}
void HandleMessage_Blit(CClient& client, CDeserialiser& message)
return ;
}
- _SysDebug("IPC::HandleMessage - command=%i", command);
(message_handlers[command])(client, message);
- _SysDebug("IPC::HandleMessage - Completed");
}
CClientFailure::CClientFailure(std::string&& what):
timeoutp = &timeout;
}
else {
- ::_SysDebug("Calling select with no timeout");
+ //::_SysDebug("Calling select with no timeout");
timeoutp = 0;
}
int rv = ::_SysSelect(nfd, &rfds, NULL, NULL/*&efds*/, timeoutp, 0);
size_t cmdlen = sizeof(struct ptycmd_senddata)/4 + width;
//_SysDebug(" - Offset = %i, cmdlen = %i", (dst_y * m_width + dst_x) * 4, cmdlen);
struct ptycmd_senddata cmd = {
- {PTY2D_CMD_SEND, cmdlen & 0xFF, cmdlen>>8},
+ {PTY2D_CMD_SEND, uint8_t(cmdlen & 0xFF), uint16_t(cmdlen>>8)},
(dst_y * m_width + dst_x)
};
SetBufFormat(PTYBUFFMT_2DCMD);
tAxWin4_Window *bgwin = AxWin4_CreateWindow("background");
+ unsigned int w, h;
+ AxWin4_GetScreenDimensions(0, &w, &h);
+
AxWin4_MoveWindow(bgwin, 0,0);
- AxWin4_ResizeWindow(bgwin, 640,480);
- //AxWin4_SetWindowFlags(bgwin, AXWIN4_WNDFLAG_NODECORATE|AXWIN4_WNDFLAG_KEEPBELOW);
+ AxWin4_ResizeWindow(bgwin, w,h);
+ AxWin4_SetWindowFlags(bgwin, AXWIN4_WNDFLAG_NODECORATE|AXWIN4_WNDFLAG_KEEPBELOW);
+ AxWin4_ShowWindow(bgwin, true);
// Load image
- //char *image = malloc(640*480*4);
- //AxWin4_DrawBitmap(bgwin, 0, 0, 640, 480, image);
+ uint32_t *image = malloc(w*h*4);
+ for(size_t i = 0; i < w*h; i ++ )
+ image[i] = rand();
+
+ AxWin4_DrawBitmap(bgwin, 0, 0, w, h, (void*)image);
_SysDebug("Beginning queue");
namespace AxWin {
extern void SendMessage(CSerialiser& message);
+extern void RecvMessage(CDeserialiser& message);
};
/*
+ * Acess2 GUIv4 (AxWin4)
+ * - By John Hodge (thePowersGang)
+ *
+ * axwin4/axwin.h
+ * - Client library interface header
*/
#ifndef _LIBAXWIN4_AXWIN4_AXWIN_H_
#define _LIBAXWIN4_AXWIN4_AXWIN_H_
extern bool AxWin4_WaitEventQueue(uint64_t Timeout);
extern bool AxWin4_WaitEventQueueSelect(int nFDs, fd_set *rfds, fd_set *wfds, fd_set *efds, uint64_t Timeout);
+extern void AxWin4_GetScreenDimensions(unsigned int ScreenIndex, unsigned int *Width, unsigned int *Height);
+
extern tAxWin4_Window *AxWin4_CreateWindow(const char *Name);
-extern void AxWin4_ShowWindow(tAxWin4_Window *Window);
+extern void AxWin4_DestroyWindow(tAxWin4_Window *Window);
+extern void AxWin4_ShowWindow(tAxWin4_Window *Window, bool Shown);
+extern void AxWin4_SetWindowFlags(tAxWin4_Window *Window, unsigned int NewFlags);
extern void AxWin4_SetTitle(tAxWin4_Window *Window, const char *Title);
extern void AxWin4_MoveWindow(tAxWin4_Window *Window, int X, int Y);
extern void AxWin4_ResizeWindow(tAxWin4_Window *Window, unsigned int W, unsigned int H);
+
extern void AxWin4_DrawBitmap(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, void *Data);
+#include "definitions.h"
+
#ifdef __cplusplus
}
--- /dev/null
+/*
+ * Acess2 GUIv4 (AxWin4)
+ * - By John Hodge (thePowersGang)
+ *
+ * axwin4/definitions.h
+ * - Shared definitions (Client and server)
+ */
+#ifndef _LIBAXWIN4_AXWIN4_DEFINITIONS_H_
+#define _LIBAXWIN4_AXWIN4_DEFINITIONS_H_
+
+#define AXWIN4_WNDFLAG_NODECORATE 0x01
+#define AXWIN4_WNDFLAG_KEEPBELOW 0x02
+#define AXWIN4_WNDFLAG_KEEPABOVE 0x04
+
+#endif
+
#include "include/common.hpp"
#include "include/IIPCChannel.hpp"
#include "include/CIPCChannel_AcessIPCPipe.hpp"
+#include <ipc_proto.hpp>
#include <algorithm>
+#include <mutex>
+#include <stdexcept>
#include <cstring>
#include <cstdio>
namespace AxWin {
IIPCChannel* gIPCChannel;
+::std::mutex glSyncReply;
+bool gSyncReplyValid;
+CDeserialiser gSyncReplyBuf;
extern "C" bool AxWin4_Connect(const char *URI)
{
extern "C" bool AxWin4_WaitEventQueue(uint64_t Timeout)
{
- AxWin4_WaitEventQueueSelect(0, NULL, NULL, NULL, Timeout);
+ return AxWin4_WaitEventQueueSelect(0, NULL, NULL, NULL, Timeout);
}
extern "C" bool AxWin4_WaitEventQueueSelect(int nFDs, fd_set *rfds, fd_set *wfds, fd_set *efds, uint64_t Timeout)
{
gIPCChannel->Send(message);
}
+void RecvMessage(CDeserialiser& message)
+{
+ uint8_t id = message.ReadU8();
+ switch(id)
+ {
+ case IPCMSG_REPLY:
+ // Flag reply and take a copy of this message
+ if( gSyncReplyValid )
+ {
+ // Oh... that was unexpected
+ _SysDebug("Unexpected second reply message %i", message.ReadU8());
+ }
+ else
+ {
+ gSyncReplyValid = true;
+ gSyncReplyBuf = message;
+ }
+ break;
+ default:
+ _SysDebug("TODO: RecvMessage(%i)", id);
+ break;
+ }
+}
+
+CDeserialiser GetSyncReply(CSerialiser& request, unsigned int Message)
+{
+ ::std::lock_guard<std::mutex> lock(glSyncReply);
+ gSyncReplyValid = false;
+ // Send once lock is acquired
+ SendMessage(request);
+
+ while( !gSyncReplyValid )
+ {
+ // Tick along
+ if( !AxWin4_WaitEventQueue(0) )
+ throw ::std::runtime_error("Connection dropped while waiting for reply");
+ }
+
+ uint8_t id = gSyncReplyBuf.ReadU8();
+ if( id != Message )
+ {
+ _SysDebug("Unexpected reply message '%i', message.ReadU8()");
+ }
+
+ return gSyncReplyBuf;
+}
+
+extern "C" void AxWin4_GetScreenDimensions(unsigned int ScreenIndex, unsigned int *Width, unsigned int *Height)
+{
+ CSerialiser req;
+ req.WriteU8(IPCMSG_GETGLOBAL);
+ req.WriteU16(IPC_GLOBATTR_SCREENDIMS);
+ req.WriteU8(ScreenIndex);
+
+ CDeserialiser response = GetSyncReply(req, IPCMSG_GETGLOBAL);
+ if( response.ReadU16() != IPC_GLOBATTR_SCREENDIMS ) {
+
+ }
+
+ *Width = response.ReadU16();
+ *Height = response.ReadU16();
+
+ _SysDebug("AxWin4_GetScreenDimensions: %i = %ix%i", ScreenIndex, *Width, *Height);
+}
IIPCChannel::~IIPCChannel()
{
* ipc_acessipcpipe.c
* - Acess2 /Devices/ipcpipe/ IPC Channel
*/
+#include "include/common.hpp"
#include "include/CIPCChannel_AcessIPCPipe.hpp"
#include <system_error>
#include <cerrno>
{
if( FD_ISSET(m_fd, &fds) )
{
+ ::std::vector<uint8_t> rxbuf(4096);
+ size_t len = _SysRead(m_fd, rxbuf.data(), rxbuf.capacity());
+ if( len == (size_t)-1 )
+ throw ::std::system_error(errno, ::std::system_category());
+ rxbuf.resize(len);
+ _SysDebug("CClient_AcessIPCPipe::HandleReceive - Rx %i/%i bytes", len, rxbuf.capacity());
+ _SysDebugHex("CClient_AcessIPCPipe::HandleReceive", rxbuf.data(), len);
+
+ CDeserialiser msg(rxbuf);
+ ::AxWin::RecvMessage( msg );
}
return true;
}
throw ::std::length_error("CIPCChannel_AcessIPCPipe::Send");
}
_SysDebug("CIPCChannel_AcessIPCPipe::Send(%i bytes)", serialised.size());
+ //_SysDebugHex("CIPCChannel_AcessIPCPipe::Send", serialised.data(), serialised.size());
+
size_t rv = _SysWrite(m_fd, serialised.data(), serialised.size());
if( rv != serialised.size() ) {
throw ::std::system_error(errno, ::std::system_category());
#include <axwin4/axwin.h>
#include "include/common.hpp"
#include <ipc_proto.hpp>
+#include <vector>
+#include <algorithm>
+#include <mutex>
namespace AxWin {
+static const int MAX_WINDOW_ID = 16;
+static ::std::mutex glWindowList;
+static ::std::vector<tAxWin4_Window*> gWindowList;
+
extern "C" tAxWin4_Window *AxWin4_CreateWindow(const char *Name)
{
// Allocate a window ID
+ ::std::lock_guard<std::mutex> lock(glWindowList);
+ int id = ::std::find(gWindowList.begin(), gWindowList.end(), nullptr) - gWindowList.end();
+ if( id >= MAX_WINDOW_ID ) {
+ throw ::std::runtime_error("AxWin4_CreateWindow - Out of IDs (TODO: Better exception)");
+ }
+ if( id == gWindowList.size() )
+ {
+ gWindowList.push_back(nullptr);
+ }
// Create window structure locally
tAxWin4_Window *ret = new tAxWin4_Window();
- ret->m_id = 0;
+ gWindowList[id] = ret;
+ ret->m_id = id;
// Request creation of window
CSerialiser message;
message.WriteU8(IPCMSG_CREATEWIN);
return ret;
}
-extern "C" void AxWin4_ShowWindow(tAxWin4_Window *Window)
+extern "C" void AxWin4_ShowWindow(tAxWin4_Window *Window, bool Show)
{
CSerialiser message;
message.WriteU8(IPCMSG_SETWINATTR);
message.WriteU16(Window->m_id);
message.WriteU16(IPC_WINATTR_SHOW);
- message.WriteU8(1);
+ message.WriteU8( (Show ? 1 : 0) );
+ ::AxWin::SendMessage(message);
+}
+
+extern "C" void AxWin4_SetWindowFlags(tAxWin4_Window *Window, unsigned int Flags)
+{
+ CSerialiser message;
+ message.WriteU8(IPCMSG_SETWINATTR);
+ message.WriteU16(Window->m_id);
+ message.WriteU16(IPC_WINATTR_FLAGS);
+ message.WriteU8( Flags );
::AxWin::SendMessage(message);
}
USE_CXX_LINK := yes\r
\r
OBJ = misc.o new.o guard.o cxxabi.o typeinfo.o\r
-OBJ += string.o\r
+OBJ += string.o mutex.o\r
OBJ += exceptions.o exception_handling.o system_error.o\r
OBJ += gxx_personality.o\r
DEPFILES := $(OBJ:%.o=%.d)\r
logic_error(what_str)
{
}
+
+::std::runtime_error::runtime_error(const ::std::string& what_str):
+ exception(what_str)
+{
+}
+
extern void debug(const char *, ...);
};
+#if _CXX11_AVAIL
+#define _CXX11_MOVE(val) ::std::move(val)
+#else
+#define _CXX11_MOVE(val) val
+#endif
+
#endif
* Acess2 C++ Library
* - By John Hodge (thePowersGang)
*
- * string (header)
- * - C++'s String type
+ * algorithm (header)
+ * - C++'s generic algorithms
*/
#ifndef _LIBCXX_ALGORITHM_
#define _LIBCXX_ALGORITHM_
+#include <utility>
+
+#include "_libcxx_helpers.h"
+
namespace std {
+// --- Non-modifiying sequence operations ---
+#if _CXX11_AVAIL
+// TODO: all_of
+// TODO: any_of
+// TODO: none_of
+#endif
+template <class InputIterator, class Function>
+Function for_each(InputIterator first, InputIterator last, Function fn)
+{
+ while( first != last )
+ {
+ fn( *first );
+ ++ first;
+ }
+ return _CXX11_MOVE(fn);
+}
+
+template <class InputIterator, class T>
+InputIterator find(InputIterator first, InputIterator last, const T& val)
+{
+ while( first != last )
+ {
+ if( *first == val )
+ return first;
+ ++ first;
+ }
+ return last;
+}
+// TODO: find_if
+// TODO: find_if_not (C++11)
+// TODO: find_end
+// TODO: find_first_of
+
// Maximum
template <class T>
const T& max(const T& a, const T& b)
public ::std::_bits::allocator_real<T>
{
public:
-/*
- typedef T value_type;
- typedef T* pointer;
- typedef T& reference;
- typedef const T* const_pointer;
- typedef const T& const_reference;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
-
- template <class Type>
- struct rebind
- {
- typedef allocator<Type> other;
- };
-
- allocator_noconstruct() throw() {
- }
- allocator_noconstruct(const allocator_noconstruct& alloc __attribute__((unused))) throw() {
- }
- template <class U>
- allocator_noconstruct(const allocator_noconstruct<U>& alloc) throw() {
- }
- ~allocator_noconstruct() throw() {
- }
-
- pointer address(reference x) const {
- return &x;
- }
- const_pointer address(const_reference x) const {
- return &x;
- }
- pointer allocate(size_type n, const void* hint=0) {
- hint = hint;
- return static_cast<pointer>( ::operator new (n * sizeof(value_type)) );
- }
- void deallocate(pointer p, size_type n) {
- n=n;
- ::operator delete(p);
- }
- size_type max_size() {
- return ((size_type)-1) / sizeof(value_type);
- }
-*/
-
void construct( typename allocator_real<T>::pointer p, typename allocator_real<T>::const_reference val ) {
*p = val;
}
- // C++11
- #if _CXX11_AVAIL
- template<class U, class... Args>
- void construct( U* p, Args&&... args ) {
- }
- #endif
void destroy(typename allocator_real<T>::pointer p) {
}
};
{
};
+#if 1
template <>
class allocator<unsigned char>:
public _bits::allocator_noconstruct<unsigned char>
public _bits::allocator_noconstruct<unsigned long>
{
};
+#endif
};
}
m_item_count = 0;
}
+
+ void splice(iterator position, list& x) {
+ splice(position, x, x.begin(), x.end());
+ }
+ void splice(iterator position, list& x, iterator i) {
+ splice(position, x, i, x.end());
+ }
+ void splice(iterator position, list& x, iterator first, iterator last);
+
+private:
+ class _equal
+ {
+ const value_type& m_val;
+ public:
+ _equal(const value_type& val):
+ m_val(val)
+ {
+ };
+ bool operator() (const value_type& v1)
+ {
+ return m_val == v1;
+ }
+ };
+public:
+ void remove(const value_type& val) {
+ remove_if(_equal(val));
+ }
+ template <class Predicate> void remove_if(Predicate pred) {
+ for( iterator it = begin(); it != end(); )
+ {
+ if( pred(*it) )
+ it = erase(it);
+ else
+ ++ it;
+ }
+ }
+
+ void unique();
+ template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
+
+ void merge(list& x);
+ template <class Compare> void merge(list& x, Compare comp);
+
+ void sort();
+ template <class Compare> void sort(Compare comp);
+
+ void reverse() throw();
private:
iterator insert_item(iterator position, item_type *newi) {
m_item_count ++;
--- /dev/null
+/*
+ * Acess2 C++ Library
+ * - By John Hodge (thePowersGang)
+ *
+ * mutex (header)
+ * - C++11's tutex handling
+ */
+#ifndef _LIBCXX_MUTEX_
+#define _LIBCXX_MUTEX_
+
+#include "_libcxx_helpers.h"
+
+#if !_CXX11_AVAIL
+# error "<mutex> requires C++11 support"
+#endif
+
+namespace std {
+
+#if _CXX11_AVAIL
+
+class mutex
+{
+public:
+ constexpr mutex() noexcept:
+ m_flag(false)
+ {
+ }
+ mutex(const mutex&) = delete;
+ mutex& operator=(const mutex&) = delete;
+ ~mutex();
+
+ void lock();
+ bool try_lock();
+ void unlock();
+
+ typedef void* native_handle;
+private:
+ // TODO: Proper userland mutex support
+ bool m_flag;
+};
+
+struct defer_lock_t {};
+struct try_to_lock_t {};
+struct adopt_lock_t {};
+
+template< class Mutex >
+class lock_guard
+{
+public:
+ typedef Mutex mutex_type;
+private:
+ mutex_type& m_lock;
+public:
+ lock_guard(mutex_type& m):
+ m_lock(m)
+ {
+ m_lock.lock();
+ }
+ lock_guard(mutex_type& m, std::adopt_lock_t t):
+ m_lock(m)
+ {
+ // Adopted
+ }
+ ~lock_guard() {
+ m_lock.unlock();
+ }
+};
+
+#endif
+
+}; // namespace std
+
+#endif
+
+// vim: ft=cpp
+
//extern void* operator new(size_t size) throw (::std::bad_alloc);
//extern void* operator new(size_t size, const std::nothrow_t& nothrow_value) throw();
-extern void* operator new(size_t size, void* ptr) throw();
+inline void* operator new(size_t /*size*/, void* ptr) throw() {
+ return ptr;
+}
//extern void* operator new[](size_t size) throw (::std::bad_alloc);
//extern void* operator new[](size_t size, const std::nothrow_t& nothrow_value) throw();
-extern void* operator new[](size_t size, void* ptr) throw();
+inline void* operator new[](size_t /*size*/, void* ptr) throw() {
+ return ptr;
+}
#endif
namespace std {
namespace _bits {
-template <class T, typename size_type>
+template <class VectorType, class T>
class vector_iterator//:
//public random_acess_iterator_tag
{
+ friend VectorType;
+
+ typedef typename VectorType::size_type size_type;
+ typedef typename VectorType::difference_type difference_type;
+
T* m_array;
size_type m_pos;
size_type m_max;
T& operator->() const {
return m_array[m_pos];
}
+ T& operator[](difference_type n) {
+ return *(*this + n);
+ }
vector_iterator& operator++() {
if(m_pos < m_max) {
m_pos ++;
}
return *this;
}
+ const vector_iterator operator++(int) {
+ vector_iterator ret(*this);
+ ++*this;
+ return ret;
+ }
vector_iterator& operator--() {
if(m_pos > 0) {
m_pos --;
}
return *this;
}
+ const vector_iterator operator--(int) {
+ vector_iterator ret(*this);
+ --*this;
+ return ret;
+ }
+ vector_iterator& operator+=(difference_type n) {
+ if( n < 0 )
+ return (*this -= -n);
+ if( n > 0 )
+ m_pos = (m_pos + n < m_max ? m_pos + n : m_max);
+ return *this;
+ }
+ vector_iterator& operator-=(difference_type n) {
+ if( n < 0 )
+ return (*this += -n);
+ if( n > 0 )
+ m_pos = (m_pos >= n ? m_pos - n : 0);
+ return *this;
+ }
+ const difference_type operator-(const vector_iterator& it2) const {
+ //_libcxx_assert(m_array == it2.m_array);
+ return m_pos - it2.m_pos;
+ }
+ bool operator<(const vector_iterator& o) const { return m_pos < o.m_pos; }
+ bool operator>(const vector_iterator& o) const { return m_pos > o.m_pos; }
+ bool operator<=(const vector_iterator& o) const { return m_pos <= o.m_pos; }
+ bool operator>=(const vector_iterator& o) const { return m_pos >= o.m_pos; }
};
+#define vector_iterator_tpl class VectorType, class T
+#define vector_iterator vector_iterator<VectorType, T>
+template <vector_iterator_tpl>
+const vector_iterator operator+(const vector_iterator& it, typename VectorType::difference_type n) {
+ return vector_iterator(it) += n;
+}
+template <vector_iterator_tpl>
+const vector_iterator operator+(typename VectorType::difference_type n, const vector_iterator& it) {
+ return vector_iterator(it) += n;
+}
+template <vector_iterator_tpl>
+const vector_iterator operator-(const vector_iterator& it, typename VectorType::difference_type n) {
+ return vector_iterator(it) -= n;
+}
+#undef vector_iterator_tpl
+#undef vector_iterator
+
}
template <class T, class Alloc = allocator<T> >
typedef typename allocator_type::const_pointer const_pointer;
typedef int difference_type;
typedef size_t size_type;
- typedef ::std::_bits::vector_iterator<T,size_type> iterator;
- typedef ::std::_bits::vector_iterator<const T,size_type> const_iterator;
+ typedef ::std::_bits::vector_iterator<vector,T> iterator;
+ typedef ::std::_bits::vector_iterator<vector,const T> const_iterator;
private:
allocator_type m_alloc;
{
resize(n, val);
}
+ template <class InputIterator>
+ vector(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()):
+ vector(alloc)
+ {
+ insert(begin(), first, last);
+ }
vector(const vector& x):
vector(x.m_alloc)
{
*this = x;
}
+ #if _CXX11_AVAIL
+ vector(vector&& x):
+ m_alloc(x.m_alloc),
+ m_size(x.m_size),
+ m_capacity(x.m_capacity),
+ m_data(x.m_data)
+ {
+ x.m_data = nullptr;
+ x.m_capacity = 0;
+ x.m_size = 0;
+ }
+ #endif
+ vector& operator=(const vector& x)
+ {
+ clear();
+ m_alloc.deallocate(m_data, m_capacity);
+ m_capacity = 0;
+
+ reserve(x.size());
+ for( size_type i = 0; i < x.size(); i ++ )
+ push_back( x[i] );
+
+ return *this;
+ }
~vector()
{
clear();
m_alloc.deallocate(m_data, m_capacity);
+ m_capacity = 0;
}
// Iterators
- iterator begin() {
- return iterator(m_data, 0, m_size);
- }
- const_iterator begin() const {
- return const_iterator(m_data, 0, m_size);
- }
- iterator end() {
- return iterator(m_data, m_size, m_size);
- }
- const_iterator end() const {
- return const_iterator(m_data, m_size, m_size);
- }
+ iterator begin() { return iterator_to(0); }
+ const_iterator begin() const { return iterator_to(0); }
+ iterator end() { return iterator_to(m_size); }
+ const_iterator end() const { return iterator_to(m_size); }
// Capacity
size_type size() const {
}
}
iterator insert(iterator position, const value_type& val) {
- inesert(position, 1, val);
- return position;
+ insert(position, 1, val);
+ return iterator_to(position.m_pos);
+ }
+ void insert(iterator position, size_type n, const value_type& val) {
+ reserve(m_size + n);
+ if( position != end() ) {
+ ::_sys::debug("TODO: vector::insert within vector (%i!=%i)",
+ position-begin(), end()-begin());
+ ::_sys::abort();
+ }
+ size_type pos = m_size;
+ while( n -- )
+ {
+ //::_sys::debug("vector::insert - %x at %i", val, pos);
+ m_alloc.construct( &m_data[pos], val );
+ pos ++;
+ m_size ++;
+ }
+ }
+ template <class InputIterator>
+ void insert(iterator position, InputIterator first, InputIterator last) {
+ InputIterator it = first;
+ size_type len = 0;
+ while(it != last) {
+ ++ it;
+ len ++;
+ }
+ reserve(m_size + len);
+
+ it = first;
+ while(it != last)
+ {
+ //::_sys::debug("vector::insert - to %i, from %p:%i",
+ // position.m_pos, it.m_array, it.m_pos);
+ position = insert(position, *it) + 1;
+ ++it;
+ }
}
- void insert(iterator position, size_type n, const value_type& val);
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
//void swap(vector& x) {
}
m_size = 0;
}
+private:
+ iterator iterator_to(size_type index) {
+ _libcxx_assert(index <= m_size);
+ return iterator(m_data, index, m_size);
+ }
+ const_iterator iterator_to(size_type index) const {
+ _libcxx_assert(index <= m_size);
+ return const_iterator(m_data, index, m_size);
+ }
};
}; // namespace std
--- /dev/null
+/*
+ * Acess2 C++ Library
+ * - By John Hodge (thePowersGang)
+ *
+ * mutex.cc
+ * - ::std::mutex and helpers
+ */
+#include <mutex>
+#include <system_error>
+#include <cerrno>
+
+// === CODE ===
+::std::mutex::~mutex()
+{
+
+}
+
+void ::std::mutex::lock()
+{
+ if( m_flag )
+ {
+ _sys::debug("TODO: userland mutexes");
+ throw ::std::system_error(ENOTIMPL, ::std::system_category());
+ }
+ m_flag = true;
+}
+
+bool ::std::mutex::try_lock()
+{
+ bool rv = m_flag;
+ m_flag = true;
+ return !rv;
+}
+
+void ::std::mutex::unlock()
+{
+ m_flag = false;
+}
+