Boost logo

Boost-Commit :

From: jefffaust_at_[hidden]
Date: 2007-05-21 08:08:00


Author: jefffaust
Date: 2007-05-21 08:07:59 EDT (Mon, 21 May 2007)
New Revision: 4155
URL: http://svn.boost.org/trac/boost/changeset/4155

Log:
initial checkin

Added:
   sandbox/explore/boost/explore/stream_state.hpp

Added: sandbox/explore/boost/explore/stream_state.hpp
==============================================================================
--- (empty file)
+++ sandbox/explore/boost/explore/stream_state.hpp 2007-05-21 08:07:59 EDT (Mon, 21 May 2007)
@@ -0,0 +1,74 @@
+//
+// stream_state.hpp - maintain user-defined state per stream.
+//
+// The single entry point, get_stream_state, wraps the arcane ios
+// interfaces xalloc, pword, and register_callback.
+//
+// Built, run, and tested on exactly one compiler (VC8).
+//
+// Copyright (c) 2007 Jeff Faust
+//
+// 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)
+//
+
+#ifndef stream_state_h_
+#define stream_state_h_
+
+#include <xiosbase> // TODO: is this a standard header?
+#include <memory>
+
+namespace explore
+{
+ // forward declaration for deletion callback
+ template<typename T>
+ T* get_stream_state(std::ios_base& stream, bool create);
+
+ namespace detail
+ {
+ // returns an index into the ios_base container of user-defined data. This will
+ // create exactly one index per type T.
+ template<typename T>
+ int get_stream_state_index(std::ios_base& stream)
+ {
+ static int index = stream.xalloc();
+ return index;
+ }
+
+ // deletion callback for extra state
+ template<typename T>
+ void delete_extra_state(std::ios_base::event e, std::ios_base& stream, int arg)
+ {
+ if( std::ios_base::erase_event == e && arg == get_stream_state_index<T>(stream) )
+ {
+ delete get_stream_state<T>(stream);
+ stream.pword(arg) = 0;
+ }
+ }
+ }
+
+ // returns state information stored in the stream for the given type. Will allocate
+ // state data if needed and create == true. If create == false and the data does not
+ // already exist, it will return 0.
+ // T: the user-defined state class. Must be default constructible.
+ template<typename T>
+ T* get_stream_state(std::ios_base& stream, bool create = true)
+ {
+ // grab reserved index
+ int index = detail::get_stream_state_index<T>(stream);
+
+ // grab state data at that index, casting from void*
+ T*& state = reinterpret_cast<T*&>(stream.pword(index));
+ if( !state && create )
+ {
+ // both creating a new T and registering the callback allocate memory. Use
+ // auto_ptr to satisfy the strong exception guarantee.
+ std::auto_ptr<T> pt(new T);
+ stream.register_callback(detail::delete_extra_state<T>, index);
+ state = pt.release();
+ }
+ return state;
+ }
+}
+
+#endif


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