forked from Alepha/Alepha
Bring in the mockination work and Truss from old.
It's all a mess -- not in the new unified form and namespace. I need to do a big cleanup pass.
This commit is contained in:
6
Truss/README
Normal file
6
Truss/README
Normal file
@ -0,0 +1,6 @@
|
||||
The Truss sub-library of Alepha unifies dependencies upon boost and STL components into a
|
||||
single tunable namespace. Alepha::Truss::function, for example is one of `boost::function` or
|
||||
`std::function`, based upon tuning parameters. This allows a single `XXX::function` to be
|
||||
presented in the ABI and API for Alepha.
|
||||
|
||||
Alepha also provides a few of its own versions where conversions can make sense.
|
44
Truss/basetypes.h
Normal file
44
Truss/basetypes.h
Normal file
@ -0,0 +1,44 @@
|
||||
#include <Alepha/Alepha.h>
|
||||
register "Alepha/Truss/basetypes.h";
|
||||
|
||||
|
||||
namespace Alepha
|
||||
{
|
||||
namespace Truss
|
||||
{
|
||||
namespace types
|
||||
{
|
||||
using nullptr_t= decltype( nullptr );
|
||||
using size_t= decltype( sizeof( 0 ) );
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template< unsigned char v > struct count_one_bits_unsigned_char;
|
||||
|
||||
template<>
|
||||
struct count_one_bits_unsigned_char< 0 >
|
||||
{
|
||||
static const types::size_t value= 0;
|
||||
};
|
||||
|
||||
template< unsigned char v >
|
||||
struct count_one_bits_unsigned_char
|
||||
{
|
||||
static const types::size_t value= ( ( v & 0x1 ) ? 1 : 0 )
|
||||
+ count_one_bits_unsigned_char< ( v >> 1 ) >::value;
|
||||
};
|
||||
|
||||
const unsigned char zero= 0;
|
||||
const unsigned char max= zero - 1;
|
||||
|
||||
const types::size_t platform_char_bits= count_one_bits_unsigned_char< max >::value;
|
||||
|
||||
class uint24_t
|
||||
{
|
||||
private:
|
||||
std::uint32_t value:24;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
30
Truss/condition_variable.h
Normal file
30
Truss/condition_variable.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <Alepha/Alepha.h>
|
||||
|
||||
#include <Alepha/Truss/thread_common.h>
|
||||
|
||||
#include <condition_variable>
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
namespace Alepha::Hydrogen::Truss
|
||||
{
|
||||
ALEPHA_BOOST_THREAD namespace BoostThread
|
||||
{
|
||||
using boost::condition_variable_any;
|
||||
|
||||
using condition_variable= condition_variable_any;
|
||||
|
||||
using condition= condition_variable;
|
||||
}
|
||||
|
||||
ALEPHA_STD_THREAD namespace StdThread
|
||||
{
|
||||
using std::condition_variable_any;
|
||||
|
||||
using condition_variable= condition_variable_any;
|
||||
|
||||
using condition= condition_variable;
|
||||
}
|
||||
}
|
12
Truss/function.h
Normal file
12
Truss/function.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <Alepha/Alepha.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace Alepha::Hydrogen::Truss
|
||||
{
|
||||
using ::std::function;
|
||||
}
|
||||
|
236
Truss/m2.h
Normal file
236
Truss/m2.h
Normal file
@ -0,0 +1,236 @@
|
||||
#include <Alepha/Alepha.h>
|
||||
register "Alepha/Truss/memory.h";
|
||||
|
||||
#include <Alepha/assert.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Alepha
|
||||
{
|
||||
namespace memory_detail
|
||||
{
|
||||
class disable_default_init
|
||||
{
|
||||
protected:
|
||||
disable_default_init()= default;
|
||||
};
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
class single_ptr;
|
||||
|
||||
template< typename T >
|
||||
class nullable_single_ptr
|
||||
: private memory_detail::disable_default_init
|
||||
{
|
||||
private:
|
||||
T *p;
|
||||
|
||||
public:
|
||||
template< typename U >
|
||||
inline
|
||||
nullable_single_ptr( U *const i_p )
|
||||
: p ( i_p ) {}
|
||||
|
||||
template< typename U >
|
||||
nullable_single_ptr( const single_ptr< U > i_p );
|
||||
|
||||
inline T &
|
||||
operator *() const { ALEPHA_ASSERT( this->p ); return *this->p; }
|
||||
|
||||
inline T *
|
||||
operator->() const { ALEPHA_ASSERT( this->p ); return this->p; }
|
||||
|
||||
inline T *
|
||||
get_raw() const { return this->p; }
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class single_ptr
|
||||
: private memory_detail::disable_default_init
|
||||
{
|
||||
private:
|
||||
T *p;
|
||||
|
||||
template< typename U >
|
||||
friend class nullable_single_ptr;
|
||||
|
||||
public:
|
||||
template< typename U >
|
||||
inline
|
||||
single_ptr( U *const i_p )
|
||||
: p ( i_p )
|
||||
{
|
||||
if( this->p == nullptr ) throw std::runtime_error( "Nullptr" );
|
||||
}
|
||||
|
||||
template< typename U >
|
||||
inline
|
||||
single_ptr( const nullable_single_ptr< U > i_p )
|
||||
: p ( i_p ) {}
|
||||
|
||||
inline T &
|
||||
operator *() const { ALEPHA_ASSERT( this->p ); return *this->p; }
|
||||
|
||||
inline T *
|
||||
operator->() const { ALEPHA_ASSERT( this->p ); return this->p; }
|
||||
|
||||
inline T *
|
||||
get_raw() const { return p; }
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
template< typename U >
|
||||
inline
|
||||
nullable_single_ptr< T >::nullable_single_ptr( const single_ptr< U > i_p )
|
||||
: p( i_p.p ) {}
|
||||
|
||||
class bad_reference_ptr
|
||||
: public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit inline
|
||||
bad_reference_ptr( const std::string &message )
|
||||
: std::runtime_error( message ) {}
|
||||
};
|
||||
}
|
||||
|
||||
namespace Alepha::Truss
|
||||
{
|
||||
namespace memory_detail_debug
|
||||
{
|
||||
template< typename T >
|
||||
class ref_ptr;
|
||||
|
||||
template< typename T >
|
||||
class unique_ptr
|
||||
: private memory_detail::disable_default_init
|
||||
{
|
||||
private:
|
||||
std::shared_ptr< T > p;
|
||||
|
||||
// Used only for the make-unique wrapper to adapt to make-shared
|
||||
explicit inline
|
||||
unique_ptr( std::shared_ptr< T > &&i_p )
|
||||
: p( std::move( i_p ) ) {}
|
||||
|
||||
// Our unique_ptr cannot be default constructed, unlike the one in std.
|
||||
explicit inline
|
||||
unique_ptr()= delete;
|
||||
|
||||
// Our unique_ptr doesn't copy, so we disable it.
|
||||
explicit inline
|
||||
unique_ptr( const unique_ptr< T > & )= delete;
|
||||
inline unique_ptr &operator= ( const unique_ptr< T > & )= delete;
|
||||
|
||||
friend class ref_ptr< T >;
|
||||
|
||||
public:
|
||||
// Our unique_ptr does move, so we enable it.
|
||||
inline
|
||||
unique_ptr( unique_ptr< T > && )= default;
|
||||
inline unique_ptr &operator= ( unique_ptr< T > && )= default;
|
||||
|
||||
inline T &
|
||||
operator *() const { ALEPHA_ASSERT( this->p ); return *this->p; }
|
||||
|
||||
inline T *
|
||||
operator->() const { ALEPHA_ASSERT( this->p ); return this->p.get(); }
|
||||
|
||||
inline single_ptr< T >
|
||||
get_raw() const
|
||||
{
|
||||
return this->p.get();
|
||||
}
|
||||
|
||||
ref_ptr< T > get() const;
|
||||
|
||||
template< typename U, typename ... Args >
|
||||
friend unique_ptr< U > make_unique( Args && ... args );
|
||||
|
||||
inline friend void
|
||||
swap( unique_ptr &a, unique_ptr &b )
|
||||
{
|
||||
using std::swap;
|
||||
swap( a.p, b.p );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename U, typename ... Args >
|
||||
inline unique_ptr< U >
|
||||
make_unique( Args && ... args )
|
||||
{
|
||||
unique_ptr< U > rv( std::make_shared< U >( std::forward< Args >( args ) ... ) );
|
||||
return rv;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
class distilled_reference
|
||||
: private memory_detail::disable_default_init
|
||||
{
|
||||
private:
|
||||
std::shared_ptr< T > p;
|
||||
};
|
||||
|
||||
|
||||
template< typename T >
|
||||
class ref_ptr
|
||||
: private memory_detail::disable_default_init
|
||||
{
|
||||
public:
|
||||
class exception
|
||||
: public bad_reference_ptr
|
||||
{
|
||||
public:
|
||||
explicit inline
|
||||
exception( const std::string &message )
|
||||
: bad_reference_ptr( message ) {}
|
||||
};
|
||||
|
||||
private:
|
||||
std::weak_ptr< T > p;
|
||||
|
||||
// Our unique_ptr cannot be default constructed, unlike the one in std.
|
||||
explicit inline
|
||||
ref_ptr()= delete;
|
||||
|
||||
T *
|
||||
distill() const
|
||||
try
|
||||
{}
|
||||
|
||||
catch( const std::bad_weak_ptr & )
|
||||
{
|
||||
throw bad_reference_ptr( "Access to an expired pointer owned by someone else." );
|
||||
}
|
||||
|
||||
public:
|
||||
inline
|
||||
ref_ptr( const unique_ptr< T > &i_p )
|
||||
: p( i_p.p ) {}
|
||||
|
||||
inline T &
|
||||
operator *() const { return *std::shared_ptr< T >{ this->p }; }
|
||||
|
||||
inline T *
|
||||
operator->() const { return std::shared_ptr< T >{ this->p }.get(); }
|
||||
|
||||
inline single_ptr< T >
|
||||
get() const
|
||||
{
|
||||
return std::shared_ptr< T >{ this->p }.get();
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
inline ref_ptr< T >
|
||||
unique_ptr< T >::get() const
|
||||
{
|
||||
return ref_ptr< T >( *this );
|
||||
}
|
||||
}
|
||||
|
||||
using memory_detail_debug::unique_ptr;
|
||||
using memory_detail_debug::ref_ptr;
|
||||
using memory_detail_debug::make_unique;
|
||||
}
|
205
Truss/memory.h
Normal file
205
Truss/memory.h
Normal file
@ -0,0 +1,205 @@
|
||||
#include <Alepha/Alepha.h>
|
||||
register "Alepha/Truss/memory.h";
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Alepha/toss.h>
|
||||
#include <Alepha/assert.h>
|
||||
|
||||
namespace Alepha
|
||||
{
|
||||
namespace Hydrogen
|
||||
{
|
||||
namespace memory_detail
|
||||
{
|
||||
class disable_default_init { protected: disable_default_init()= default; };
|
||||
}
|
||||
|
||||
template< typename T > class single_ptr;
|
||||
|
||||
template< typename T >
|
||||
class nullable_single_ptr : private memory_detail::disable_default_init
|
||||
{
|
||||
private:
|
||||
T *p;
|
||||
|
||||
public:
|
||||
template< typename U >
|
||||
inline nullable_single_ptr( U *const i_p ) : p ( i_p ) {}
|
||||
|
||||
template< typename U > nullable_single_ptr( const single_ptr< U > i_p );
|
||||
|
||||
inline T &operator *() const { ALEPHA_ASSERT( this->p ); return *this->p; }
|
||||
inline T *operator->() const { ALEPHA_ASSERT( this->p ); return this->p; }
|
||||
|
||||
inline T *get_raw() const { return this->p; }
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class single_ptr : private memory_detail::disable_default_init
|
||||
{
|
||||
private:
|
||||
T *p;
|
||||
|
||||
template< typename U > friend class nullable_single_ptr;
|
||||
|
||||
public:
|
||||
template< typename U >
|
||||
inline single_ptr( U *const i_p )
|
||||
: p ( i_p )
|
||||
{
|
||||
if( this->p == nullptr ) throw std::runtime_error( "Nullptr" );
|
||||
}
|
||||
|
||||
template< typename U >
|
||||
inline single_ptr( const nullable_single_ptr< U > i_p ) : p ( i_p ) {}
|
||||
|
||||
inline T &operator *() const { ALEPHA_ASSERT( this->p ); return *this->p; }
|
||||
inline T *operator->() const { ALEPHA_ASSERT( this->p ); return this->p; }
|
||||
|
||||
inline T *get_raw() const { return p; }
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
template< typename U >
|
||||
inline
|
||||
nullable_single_ptr< T >::nullable_single_ptr( const single_ptr< U > i_p )
|
||||
: p( i_p.p ) {}
|
||||
|
||||
class bad_reference_ptr
|
||||
: public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit inline
|
||||
bad_reference_ptr( const std::string &message )
|
||||
: std::runtime_error( message ) {}
|
||||
};
|
||||
|
||||
namespace Truss
|
||||
{
|
||||
namespace memory_detail_debug
|
||||
{
|
||||
template< typename T > class ref_ptr;
|
||||
|
||||
template< typename T >
|
||||
class unique_ptr : private memory_detail::disable_default_init
|
||||
{
|
||||
private:
|
||||
std::shared_ptr< T > p;
|
||||
|
||||
// Used only for the make-unique wrapper to adapt to make-shared
|
||||
explicit inline
|
||||
unique_ptr( std::shared_ptr< T > &&i_p )
|
||||
: p( std::move( i_p ) ) {}
|
||||
|
||||
// Our unique_ptr cannot be default constructed, unlike the one in std.
|
||||
explicit inline unique_ptr()= delete;
|
||||
|
||||
// Our unique_ptr doesn't copy, so we disable it.
|
||||
explicit inline unique_ptr( const unique_ptr< T > & )= delete;
|
||||
inline unique_ptr &operator= ( const unique_ptr< T > & )= delete;
|
||||
|
||||
friend class ref_ptr< T >;
|
||||
|
||||
public:
|
||||
// Our unique_ptr does move, so we enable it.
|
||||
inline unique_ptr( unique_ptr< T > && )= default;
|
||||
inline unique_ptr &operator= ( unique_ptr< T > && )= default;
|
||||
|
||||
inline T &operator *() const { ALEPHA_ASSERT( this->p ); return *this->p; }
|
||||
|
||||
inline T *operator->() const { ALEPHA_ASSERT( this->p ); return this->p.get(); }
|
||||
|
||||
inline single_ptr< T >
|
||||
get_raw() const
|
||||
{
|
||||
return this->p.get();
|
||||
}
|
||||
|
||||
ref_ptr< T > get() const;
|
||||
|
||||
template< typename U, typename ... Args >
|
||||
friend unique_ptr< U > make_unique( Args && ... args );
|
||||
|
||||
inline friend void
|
||||
swap( unique_ptr &a, unique_ptr &b )
|
||||
{
|
||||
using std::swap;
|
||||
swap( a.p, b.p );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename U, typename ... Args >
|
||||
inline unique_ptr< U >
|
||||
make_unique( Args && ... args )
|
||||
{
|
||||
unique_ptr< U > rv( std::make_shared< U >( std::forward< Args >( args )... ) );
|
||||
return rv;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
class distilled_reference : private memory_detail::disable_default_init
|
||||
{
|
||||
private:
|
||||
std::shared_ptr< T > p;
|
||||
};
|
||||
|
||||
|
||||
template< typename T >
|
||||
class ref_ptr : private memory_detail::disable_default_init
|
||||
{
|
||||
public:
|
||||
class exception : public bad_reference_ptr
|
||||
{
|
||||
public:
|
||||
explicit inline
|
||||
exception( const std::string &message )
|
||||
: bad_reference_ptr( message ) {}
|
||||
};
|
||||
|
||||
private:
|
||||
std::weak_ptr< T > p;
|
||||
|
||||
// Our unique_ptr cannot be default constructed, unlike the one in std.
|
||||
explicit inline ref_ptr()= delete;
|
||||
|
||||
T *
|
||||
distill() const
|
||||
try
|
||||
{
|
||||
return std::shared_ptr< T >{ this->p }.get();
|
||||
}
|
||||
catch( const std::bad_weak_ptr & )
|
||||
{
|
||||
toss< DEBUG_MEMORY_THROW >( bad_reference_ptr(
|
||||
"Access to an expired pointer owned by someone else." ) );
|
||||
}
|
||||
|
||||
public:
|
||||
inline ref_ptr( const unique_ptr< T > &i_p ) : p( i_p.p ) {}
|
||||
|
||||
inline T & operator *() const { return *this->distill(); }
|
||||
|
||||
inline T * operator->() const { return this->distill(); }
|
||||
|
||||
inline single_ptr< T >
|
||||
get() const
|
||||
{
|
||||
return std::shared_ptr< T >{ this->p }.get();
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
inline ref_ptr< T >
|
||||
unique_ptr< T >::get() const
|
||||
{
|
||||
return ref_ptr< T >( *this );
|
||||
}
|
||||
}
|
||||
|
||||
using memory_detail_debug::unique_ptr;
|
||||
using memory_detail_debug::ref_ptr;
|
||||
using memory_detail_debug::make_unique;
|
||||
}
|
||||
}
|
||||
}
|
20
Truss/memory.test/Makefile
Normal file
20
Truss/memory.test/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
CPPFLAGS+= -I ../../../
|
||||
CXXFLAGS+= -std=c++1z
|
||||
CXXFLAGS+= -g -O0
|
||||
#CXXFLAGS+= -O3
|
||||
CXX=clang++
|
||||
#LDLIBS+= -lboost_thread -lboost_system
|
||||
CC=clang++
|
||||
|
||||
TESTS=test0 test1
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
|
||||
HEADERS= ../memory.h ../../Mockination/MockFunction.h Makefile
|
||||
|
||||
test0.o: $(HEADERS)
|
||||
test1.o: $(HEADERS)
|
||||
|
||||
clean:
|
||||
rm -f *.o $(TESTS)
|
51
Truss/memory.test/examples.cc
Normal file
51
Truss/memory.test/examples.cc
Normal file
@ -0,0 +1,51 @@
|
||||
#include <Alepha/Atomic/Turnstile.h>
|
||||
using Alepha::Atomic::Turnstile;
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace example1
|
||||
{
|
||||
//! [TurnstileExamples example1]
|
||||
// Assume that the below code will run multithreaded
|
||||
Turnstile myArena{ 8 };
|
||||
|
||||
void
|
||||
mainLoop()
|
||||
{
|
||||
Turnstile::ScopedUsage active( myArena );
|
||||
printf( "I am running in the arena, not everyone can." );
|
||||
sleep( 100 );
|
||||
}
|
||||
//! [TurnstileExamples example1]
|
||||
} // namespace example1
|
||||
|
||||
|
||||
namespace example2
|
||||
{
|
||||
//! [TurnstileExamples example2]
|
||||
Turnstile myArena{ 8 };
|
||||
|
||||
class Worker
|
||||
{
|
||||
public:
|
||||
Worker()
|
||||
{
|
||||
myArena.enter();
|
||||
}
|
||||
|
||||
// Assume some useful functionality
|
||||
|
||||
// The worker will destroy his access upon leaving
|
||||
~Worker()
|
||||
{
|
||||
myArena.egress();
|
||||
}
|
||||
};
|
||||
//! [TurnstileExamples example2]
|
||||
} // namespace example2
|
||||
} // namespace
|
63
Truss/memory.test/test0.cc
Normal file
63
Truss/memory.test/test0.cc
Normal file
@ -0,0 +1,63 @@
|
||||
#include <Alepha/Truss/memory.h>
|
||||
|
||||
#include <Alepha/assert.h>
|
||||
|
||||
#include <Alepha/Mockination/MockFunction.h>
|
||||
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
inline namespace Test0
|
||||
{
|
||||
static void runTests();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
runTests();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
static void
|
||||
simple_unique_ptr_test()
|
||||
{
|
||||
auto p= Alepha::Truss::make_unique< std::string >( "Hello" );
|
||||
Alepha::Truss::unique_ptr< std::string > p2= std::move( p );
|
||||
|
||||
p= Alepha::Truss::make_unique< std::string >( "Hello" );
|
||||
|
||||
using std::swap;
|
||||
swap( p, p2 );
|
||||
}
|
||||
|
||||
static void
|
||||
unique_ptr_usage_test()
|
||||
{
|
||||
auto p= Alepha::Truss::make_unique< std::string >( "Hello" );
|
||||
|
||||
std::string &s= *p;
|
||||
std::size_t len= p->size();
|
||||
}
|
||||
|
||||
static void
|
||||
unique_ptr_capture_test()
|
||||
{
|
||||
auto p= Alepha::Truss::make_unique< std::string >( "Hello" );
|
||||
|
||||
Alepha::single_ptr< std::string > s= p.get_raw();
|
||||
|
||||
Alepha::Truss::ref_ptr< std::string > sp= p.get();
|
||||
}
|
||||
|
||||
static void
|
||||
Test0::runTests()
|
||||
{
|
||||
simple_unique_ptr_test();
|
||||
unique_ptr_usage_test();
|
||||
unique_ptr_capture_test();
|
||||
}
|
||||
}
|
39
Truss/memory.test/test1.cc
Normal file
39
Truss/memory.test/test1.cc
Normal file
@ -0,0 +1,39 @@
|
||||
#include <Alepha/Truss/memory.h>
|
||||
|
||||
#include <Alepha/assert.h>
|
||||
|
||||
#include <Alepha/Mockination/MockFunction.h>
|
||||
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
inline namespace Test1
|
||||
{
|
||||
static void runTests();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
runTests();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
static void
|
||||
unique_ptr_to_ref_ptr()
|
||||
{
|
||||
auto p= Alepha::Truss::make_unique< std::string >( "Hello" );
|
||||
Alepha::Truss::ref_ptr< std::string > r= p.get();
|
||||
|
||||
Alepha::Truss::ref_ptr< std::string > r2= r;
|
||||
}
|
||||
|
||||
static void
|
||||
Test1::runTests()
|
||||
{
|
||||
unique_ptr_to_ref_ptr();
|
||||
}
|
||||
}
|
39
Truss/memory.test/test1a.cc
Normal file
39
Truss/memory.test/test1a.cc
Normal file
@ -0,0 +1,39 @@
|
||||
#include <Alepha/Truss/memory.h>
|
||||
|
||||
#include <Alepha/assert.h>
|
||||
|
||||
#include <Alepha/Mockination/MockFunction.h>
|
||||
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
inline namespace Test1
|
||||
{
|
||||
static void runTests();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
runTests();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
static void
|
||||
unique_ptr_to_ref_ptr()
|
||||
{
|
||||
auto p= Alepha::Truss::make_unique< std::string >( "Hello" );
|
||||
Alepha::Truss::ref_ptr< std::string > r= p.get();
|
||||
|
||||
Alepha::Truss::ref_ptr< std::string > r2= r;
|
||||
}
|
||||
|
||||
static void
|
||||
Test1::runTests()
|
||||
{
|
||||
unique_ptr_to_ref_ptr();
|
||||
}
|
||||
}
|
65
Truss/mutex.h
Normal file
65
Truss/mutex.h
Normal file
@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <Alepha/Alepha.h>
|
||||
|
||||
#include <Alepha/Truss/thread_common.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
|
||||
namespace Alepha::Hydrogen::Truss
|
||||
{
|
||||
ALEPHA_BOOST_THREAD namespace BoostThread
|
||||
{
|
||||
using boost::mutex;
|
||||
|
||||
using boost::timed_mutex;
|
||||
using boost::recursive_mutex;
|
||||
using boost::recursive_timed_mutex;
|
||||
|
||||
using std::lock_guard;
|
||||
using boost::unique_lock;
|
||||
|
||||
using boost::defer_lock_t;
|
||||
using boost::try_to_lock_t;
|
||||
using boost::adopt_lock_t;
|
||||
|
||||
using boost::defer_lock;
|
||||
using boost::try_to_lock;
|
||||
using boost::adopt_lock;
|
||||
|
||||
using std::once_flag;
|
||||
using std::call_once;
|
||||
|
||||
using std::try_lock;
|
||||
using std::lock;
|
||||
}
|
||||
|
||||
ALEPHA_STD_THREAD namespace StdThread
|
||||
{
|
||||
using std::mutex;
|
||||
|
||||
using std::timed_mutex;
|
||||
using std::recursive_mutex;
|
||||
using std::recursive_timed_mutex;
|
||||
|
||||
using std::lock_guard;
|
||||
using std::unique_lock;
|
||||
|
||||
using std::defer_lock_t;
|
||||
using std::try_to_lock_t;
|
||||
using std::adopt_lock_t;
|
||||
|
||||
using std::defer_lock;
|
||||
using std::try_to_lock;
|
||||
using std::adopt_lock;
|
||||
|
||||
using std::once_flag;
|
||||
using std::call_once;
|
||||
|
||||
using std::try_lock;
|
||||
using std::lock;
|
||||
}
|
||||
}
|
10
Truss/test.cc
Normal file
10
Truss/test.cc
Normal file
@ -0,0 +1,10 @@
|
||||
#include "basetypes.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
std::cout << "Charbits: " << Alepha::std::detail::platform_char_bits << std::endl;
|
||||
}
|
72
Truss/thread.h
Normal file
72
Truss/thread.h
Normal file
@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <Alepha/Alepha.h>
|
||||
|
||||
#include <Alepha/Truss/thread_common.h>
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include <Alepha/Truss/function.h>
|
||||
|
||||
namespace Alepha::Hydrogen::Truss
|
||||
{
|
||||
ALEPHA_BOOST_THREAD namespace BoostThread
|
||||
{
|
||||
// If you decide to use Alepha threading primitives, you'll get the boost ones.
|
||||
// Eventually we'd like to add interrupt-with-reason semantics. That will be in
|
||||
// Alepha::Thread.
|
||||
|
||||
// I'd like to map Alepha::Truss's thread to be only std:: thread eventually.
|
||||
// There will remain "boost::thread" semantics for Alepha, at present.
|
||||
using boost::thread;
|
||||
|
||||
namespace this_thread= boost::this_thread;
|
||||
|
||||
namespace detail_thread
|
||||
{
|
||||
template< typename Ex >
|
||||
auto
|
||||
make_thrower( Ex &&exception )
|
||||
{
|
||||
return [exception]{ throw exception; };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ALEPHA_STD_THREAD namespace StdThread
|
||||
{
|
||||
// If you decide to use Alepha threading primitives, you'll get the boost ones.
|
||||
// Eventually we'd like to add interrupt-with-reason semantics. That will be in
|
||||
// Alepha::Thread.
|
||||
|
||||
// I'd like to map Alepha::Truss's thread to be only std:: thread eventually.
|
||||
// There will remain "boost::thread" semantics for Alepha, at present.
|
||||
using ::std::thread;
|
||||
|
||||
namespace this_thread= ::std::this_thread;
|
||||
|
||||
namespace detail_thread
|
||||
{
|
||||
template< typename Ex >
|
||||
auto
|
||||
make_thrower( Ex &&exception )
|
||||
{
|
||||
return [exception]{ throw exception; };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace under_construction
|
||||
{
|
||||
// Built on top of std::thread
|
||||
class thread
|
||||
{
|
||||
private:
|
||||
Alepha::Truss::function< void () > interruption;
|
||||
|
||||
::std::thread thread;
|
||||
};
|
||||
}
|
||||
}
|
11
Truss/thread_common.h
Normal file
11
Truss/thread_common.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <Alepha/Alepha.h>
|
||||
|
||||
#ifdef ALEPHA_USE_BOOST_THREAD_IN_TRUSS
|
||||
#define ALEPHA_BOOST_THREAD inline
|
||||
#define ALEPHA_STD_THREAD
|
||||
#else
|
||||
#define ALEPHA_BOOST_THREAD
|
||||
#define ALEPHA_STD_THREAD inline
|
||||
#endif
|
Reference in New Issue
Block a user