Add AbstractObject, cyclic_iterator, Journal improvements

This commit is contained in:
Vinnie Falco
2013-11-30 18:23:28 -08:00
parent 370d98a858
commit 893b2d4587
9 changed files with 680 additions and 95 deletions

View File

@@ -114,6 +114,7 @@
<ClInclude Include="..\..\beast\crypto\MurmurHash.h" /> <ClInclude Include="..\..\beast\crypto\MurmurHash.h" />
<ClInclude Include="..\..\beast\crypto\Sha256.h" /> <ClInclude Include="..\..\beast\crypto\Sha256.h" />
<ClInclude Include="..\..\beast\CStdInt.h" /> <ClInclude Include="..\..\beast\CStdInt.h" />
<ClInclude Include="..\..\beast\cyclic_iterator.h" />
<ClInclude Include="..\..\beast\FixedArray.h" /> <ClInclude Include="..\..\beast\FixedArray.h" />
<ClInclude Include="..\..\beast\HeapBlock.h" /> <ClInclude Include="..\..\beast\HeapBlock.h" />
<ClInclude Include="..\..\beast\HTTP.h" /> <ClInclude Include="..\..\beast\HTTP.h" />

View File

@@ -68,10 +68,10 @@
<Filter>beast_core</Filter> <Filter>beast_core</Filter>
</None> </None>
<None Include="..\..\beast\crypto\impl\sha2\README"> <None Include="..\..\beast\crypto\impl\sha2\README">
<Filter>beast\crypto\impl\sha2</Filter> <Filter>beast\http\crypto\impl\sha2</Filter>
</None> </None>
<None Include="..\..\beast\crypto\impl\sha2\sha2test.pl"> <None Include="..\..\beast\crypto\impl\sha2\sha2test.pl">
<Filter>beast\crypto\impl\sha2</Filter> <Filter>beast\http\crypto\impl\sha2</Filter>
</None> </None>
<None Include="..\..\scripts\compile.sh"> <None Include="..\..\scripts\compile.sh">
<Filter>scripts</Filter> <Filter>scripts</Filter>
@@ -255,15 +255,6 @@
<Filter Include="beast\config"> <Filter Include="beast\config">
<UniqueIdentifier>{1fff3bd8-44ae-41df-8dd4-8bb6f07b2908}</UniqueIdentifier> <UniqueIdentifier>{1fff3bd8-44ae-41df-8dd4-8bb6f07b2908}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="beast\crypto">
<UniqueIdentifier>{9c1ef4c4-5623-4500-859f-12d6ce5ae362}</UniqueIdentifier>
</Filter>
<Filter Include="beast\crypto\impl">
<UniqueIdentifier>{fc3d3f14-9ba1-43e4-b086-cbbd2f63b944}</UniqueIdentifier>
</Filter>
<Filter Include="beast\crypto\impl\sha2">
<UniqueIdentifier>{44489531-f44a-439a-a6ea-d32c252b1e8b}</UniqueIdentifier>
</Filter>
<Filter Include="beast\chrono"> <Filter Include="beast\chrono">
<UniqueIdentifier>{57dc7059-cbb2-437c-9c52-79825d9a4cf5}</UniqueIdentifier> <UniqueIdentifier>{57dc7059-cbb2-437c-9c52-79825d9a4cf5}</UniqueIdentifier>
</Filter> </Filter>
@@ -1107,10 +1098,10 @@
<Filter>beast</Filter> <Filter>beast</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\beast\crypto\impl\sha2\sha2.h"> <ClInclude Include="..\..\beast\crypto\impl\sha2\sha2.h">
<Filter>beast\crypto\impl\sha2</Filter> <Filter>beast\http\crypto\impl\sha2</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\beast\crypto\Sha256.h"> <ClInclude Include="..\..\beast\crypto\Sha256.h">
<Filter>beast\crypto</Filter> <Filter>beast\http\crypto</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\modules\beast_asio\async\WrapHandler.h"> <ClInclude Include="..\..\modules\beast_asio\async\WrapHandler.h">
<Filter>beast_asio\async</Filter> <Filter>beast_asio\async</Filter>
@@ -1282,7 +1273,7 @@
<Filter>beast\asio</Filter> <Filter>beast\asio</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\beast\crypto\MurmurHash.h"> <ClInclude Include="..\..\beast\crypto\MurmurHash.h">
<Filter>beast\crypto</Filter> <Filter>beast\http\crypto</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\beast\smart_ptr\AbstractObject.h"> <ClInclude Include="..\..\beast\smart_ptr\AbstractObject.h">
<Filter>beast\smart_ptr</Filter> <Filter>beast\smart_ptr</Filter>
@@ -1344,6 +1335,9 @@
<ClInclude Include="..\..\beast\insight\HookImpl.h"> <ClInclude Include="..\..\beast\insight\HookImpl.h">
<Filter>beast\insight</Filter> <Filter>beast\insight</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\beast\cyclic_iterator.h">
<Filter>beast</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\modules\beast_core\containers\AbstractFifo.cpp"> <ClCompile Include="..\..\modules\beast_core\containers\AbstractFifo.cpp">
@@ -1812,19 +1806,19 @@
<Filter>beast\http\impl</Filter> <Filter>beast\http\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\beast\crypto\impl\sha2\sha2.c"> <ClCompile Include="..\..\beast\crypto\impl\sha2\sha2.c">
<Filter>beast\crypto\impl\sha2</Filter> <Filter>beast\http\crypto\impl\sha2</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\beast\crypto\impl\sha2\sha2prog.c"> <ClCompile Include="..\..\beast\crypto\impl\sha2\sha2prog.c">
<Filter>beast\crypto\impl\sha2</Filter> <Filter>beast\http\crypto\impl\sha2</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\beast\crypto\impl\sha2\sha2speed.c"> <ClCompile Include="..\..\beast\crypto\impl\sha2\sha2speed.c">
<Filter>beast\crypto\impl\sha2</Filter> <Filter>beast\http\crypto\impl\sha2</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\beast\crypto\Crypto.cpp"> <ClCompile Include="..\..\beast\crypto\Crypto.cpp">
<Filter>beast\crypto</Filter> <Filter>beast\http\crypto</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\beast\crypto\impl\Sha256.cpp"> <ClCompile Include="..\..\beast\crypto\impl\Sha256.cpp">
<Filter>beast\crypto\impl</Filter> <Filter>beast\http\crypto\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\RelativeTime.cpp"> <ClCompile Include="..\..\beast\chrono\impl\RelativeTime.cpp">
<Filter>beast\chrono\impl</Filter> <Filter>beast\chrono\impl</Filter>
@@ -1896,7 +1890,7 @@
<Filter>beast\asio\impl</Filter> <Filter>beast\asio\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\beast\crypto\impl\MurmurHash.cpp"> <ClCompile Include="..\..\beast\crypto\impl\MurmurHash.cpp">
<Filter>beast\crypto\impl</Filter> <Filter>beast\http\crypto\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\beast\smart_ptr\impl\AbstractObject.cpp"> <ClCompile Include="..\..\beast\smart_ptr\impl\AbstractObject.cpp">
<Filter>beast\smart_ptr\impl</Filter> <Filter>beast\smart_ptr\impl</Filter>

View File

@@ -3,10 +3,6 @@
This file is part of Beast: https://github.com/vinniefalco/Beast This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com> Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies. copyright notice and this permission notice appear in all copies.

513
beast/cyclic_iterator.h Normal file
View File

@@ -0,0 +1,513 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Based on work with these copyrights:
Copyright Carl Philipp Reh 2009 - 2013.
Copyright Philipp Middendorf 2009 - 2013.
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)
Original code taken from
https://github.com/freundlich/fcppt
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef BEAST_CYCLIC_ITERATOR_H_INCLUDED
#define BEAST_CYCLIC_ITERATOR_H_INCLUDED
#include <iterator>
#include <boost/iterator/iterator_facade.hpp>
namespace beast {
//
// cyclic_iterator_fwd.hpp
//
template<
typename ContainerIterator
>
class cyclic_iterator;
//
// cyclic_iterator_category.hpp
//
namespace detail
{
template<
typename SourceCategory
>
struct cyclic_iterator_category;
template<>
struct cyclic_iterator_category<
std::forward_iterator_tag
>
{
typedef std::forward_iterator_tag type;
};
template<>
struct cyclic_iterator_category<
std::bidirectional_iterator_tag
>
{
typedef std::bidirectional_iterator_tag type;
};
template<>
struct cyclic_iterator_category<
std::random_access_iterator_tag
>
{
typedef std::bidirectional_iterator_tag type;
};
}
//
// cyclic_iterator_base.hpp
//
namespace detail
{
template<
typename ContainerIterator
>
struct cyclic_iterator_base
{
typedef boost::iterator_facade<
cyclic_iterator<
ContainerIterator
>,
typename std::iterator_traits<
ContainerIterator
>::value_type,
typename detail::cyclic_iterator_category<
typename std::iterator_traits<
ContainerIterator
>::iterator_category
>::type,
typename std::iterator_traits<
ContainerIterator
>::reference
> type;
};
}
//
// cyclic_iterator_decl.hpp
//
/**
\brief An iterator adaptor that cycles through a range
\ingroup fcpptmain
\tparam ContainerIterator The underlying iterator which must be at least a
forward iterator
A cyclic iterator can be useful in cases where you want <code>end()</code> to
become <code>begin()</code> again. For example, imagine a cycling through a
list of items which means if you skip over the last, you will return to the
first one.
This class can only increment or decrement its underlying iterator, random
access is not supported. The iterator category will be at most bidirectional.
It inherits all capabilities from <code>boost::iterator_facade</code> which
means that it will have the usual iterator operations with their semantics.
Here is a short example demonstrating its use.
\snippet cyclic_iterator.cpp cyclic_iterator
*/
template<
typename ContainerIterator
>
class cyclic_iterator
:
public detail::cyclic_iterator_base<
ContainerIterator
>::type
{
public:
/**
\brief The base type which is a <code>boost::iterator_facade</code>
*/
typedef typename detail::cyclic_iterator_base<
ContainerIterator
>::type base_type;
/**
\brief The underlying iterator type
*/
typedef ContainerIterator container_iterator_type;
/**
\brief The value type adapted from \a ContainerIterator
*/
typedef typename base_type::value_type value_type;
/**
\brief The reference type adapted from \a ContainerIterator
*/
typedef typename base_type::reference reference;
/**
\brief The pointer type adapted from \a ContainerIterator
*/
typedef typename base_type::pointer pointer;
/**
\brief The difference type adapted from \a ContainerIterator
*/
typedef typename base_type::difference_type difference_type;
/**
\brief The iterator category, either Forward or Bidirectional
*/
typedef typename base_type::iterator_category iterator_category;
/**
\brief Creates a singular iterator
*/
cyclic_iterator();
/**
\brief Copy constructs from another cyclic iterator
Copy constructs from another cyclic iterator \a other. This only works
if the underlying iterators are convertible.
\param other The iterator to copy construct from
*/
template<
typename OtherIterator
>
explicit
cyclic_iterator(
cyclic_iterator<OtherIterator> const &other
);
/**
\brief Constructs a new cyclic iterator
Constructs a new cyclic iterator, starting at \a it, inside
a range from \a begin to \a end.
\param pos The start of the iterator
\param begin The beginning of the range
\param end The end of the range
\warning The behaviour is undefined if \a pos isn't between \a begin
and \a end. Also, the behaviour is undefined, if \a begin and \a end
don't form a valid range.
*/
cyclic_iterator(
container_iterator_type const &pos,
container_iterator_type const &begin,
container_iterator_type const &end
);
/**
\brief Assigns from another cyclic iterator
Assigns from another cyclic iterator \a other. This only works if the
underlying iterators are convertible.
\param other The iterator to assign from
\return <code>*this</code>
*/
template<
typename OtherIterator
>
cyclic_iterator<ContainerIterator> &
operator=(
cyclic_iterator<OtherIterator> const &other
);
/**
\brief Returns the beginning of the range
*/
container_iterator_type
begin() const;
/**
\brief Returns the end of the range
*/
container_iterator_type
end() const;
/**
\brief Returns the underlying iterator
*/
container_iterator_type
get() const;
private:
friend class boost::iterator_core_access;
void
increment();
void
decrement();
bool
equal(
cyclic_iterator const &
) const;
reference
dereference() const;
difference_type
distance_to(
cyclic_iterator const &
) const;
private:
container_iterator_type
it_,
begin_,
end_;
};
//
// cyclic_iterator_impl.hpp
//
template<
typename ContainerIterator
>
cyclic_iterator<
ContainerIterator
>::cyclic_iterator()
:
it_(),
begin_(),
end_()
{
}
template<
typename ContainerIterator
>
template<
typename OtherIterator
>
cyclic_iterator<
ContainerIterator
>::cyclic_iterator(
cyclic_iterator<
OtherIterator
> const &_other
)
:
it_(
_other.it_
),
begin_(
_other.begin_
),
end_(
_other.end_
)
{
}
template<
typename ContainerIterator
>
cyclic_iterator<
ContainerIterator
>::cyclic_iterator(
container_iterator_type const &_it,
container_iterator_type const &_begin,
container_iterator_type const &_end
)
:
it_(
_it
),
begin_(
_begin
),
end_(
_end
)
{
}
template<
typename ContainerIterator
>
template<
typename OtherIterator
>
cyclic_iterator<
ContainerIterator
> &
cyclic_iterator<
ContainerIterator
>::operator=(
cyclic_iterator<
OtherIterator
> const &_other
)
{
it_ = _other.it_;
begin_ = _other.begin_;
end_ = _other.end_;
return *this;
}
template<
typename ContainerIterator
>
typename cyclic_iterator<
ContainerIterator
>::container_iterator_type
cyclic_iterator<
ContainerIterator
>::begin() const
{
return begin_;
}
template<
typename ContainerIterator
>
typename cyclic_iterator<
ContainerIterator
>::container_iterator_type
cyclic_iterator<
ContainerIterator
>::end() const
{
return end_;
}
template<
typename ContainerIterator
>
typename cyclic_iterator<
ContainerIterator
>::container_iterator_type
cyclic_iterator<
ContainerIterator
>::get() const
{
return it_;
}
template<
typename ContainerIterator
>
void
cyclic_iterator<
ContainerIterator
>::increment()
{
if(
begin_ != end_
&& ++it_ == end_
)
it_ = begin_;
}
template<
typename ContainerIterator
>
void
cyclic_iterator<
ContainerIterator
>::decrement()
{
if(
begin_ == end_
)
return;
if(
it_ == begin_
)
it_ =
std::prev(
end_
);
else
--it_;
}
template<
typename ContainerIterator
>
bool
cyclic_iterator<
ContainerIterator
>::equal(
cyclic_iterator const &_other
) const
{
return it_ == _other.it;
}
template<
typename ContainerIterator
>
typename cyclic_iterator<
ContainerIterator
>::reference
cyclic_iterator<
ContainerIterator
>::dereference() const
{
return *it_;
}
template<
typename ContainerIterator
>
typename cyclic_iterator<
ContainerIterator
>::difference_type
cyclic_iterator<
ContainerIterator
>::distance_to(
cyclic_iterator const &_other
) const
{
return _other.it_ - it_;
}
// Convenience function for template argument deduction
template <typename ContainerIterator>
cyclic_iterator <ContainerIterator> make_cyclic (
ContainerIterator const& pos,
ContainerIterator const& begin,
ContainerIterator const& end);
}
#endif

View File

@@ -25,13 +25,13 @@
#define BEAST_SMARTPTR_ABSTRACTOBJECT_H_INCLUDED #define BEAST_SMARTPTR_ABSTRACTOBJECT_H_INCLUDED
#include <list> #include <list>
#include <memory>
#include <stdexcept> #include <stdexcept>
#include <typeinfo> #include <typeinfo>
#include "../Atomic.h" #include "../Atomic.h"
#include "../Config.h" #include "../Config.h"
#include "../Uncopyable.h" #include "../Uncopyable.h"
#include "../intrusive/LockFreeStack.h" #include "../intrusive/LockFreeStack.h"
#include "../smart_ptr/ScopedPointer.h"
namespace beast { namespace beast {
namespace abstract { namespace abstract {
@@ -235,15 +235,17 @@ public:
Derived must be a subclass of Interface Derived must be a subclass of Interface
*/ */
template <typename Derived> template <typename Derived>
void add_interface (ScopedPointer <Derived>&& derived) void add_interface (Derived* derived)
{ {
std::unique_ptr <BasicInterface> base_interface (
derived);
if (has_interface <Derived> ()) if (has_interface <Derived> ())
throw std::invalid_argument ("non-unique"); throw std::invalid_argument ("non-unique");
m_set.emplace_back (derived); m_set.emplace_back (base_interface.release ());
} }
private: private:
typedef std::list <ScopedPointer <BasicInterface>> Set; typedef std::list <std::unique_ptr <BasicInterface>> Set;
Set m_set; Set m_set;
}; };

View File

@@ -66,8 +66,7 @@ public:
void create_interfaces (Object& object) void create_interfaces (Object& object)
{ {
object.add_interface (ScopedPointer <Interface1> ( object.add_interface (new Interface1);
new Interface1));
} }
}; };
@@ -91,8 +90,7 @@ public:
void create_interfaces (Object& object) void create_interfaces (Object& object)
{ {
object.add_interface (ScopedPointer <Interface2> ( object.add_interface (new Interface2);
new Interface2));
} }
}; };
@@ -112,12 +110,11 @@ public:
// find existing interfaces // find existing interfaces
expect (object.find_interface <Interface1> () != nullptr); expect (object.find_interface <Interface1> () != nullptr);
expect (object.find_interface <Interface2> () != nullptr); expect (object.find_interface <Interface2> () != nullptr);
// add duplicate interface // add duplicate interface
try try
{ {
object.add_interface (ScopedPointer <Interface1> ( object.add_interface (new Interface1);
new Interface1));
fail ("uncaught exeption"); fail ("uncaught exeption");
} }
catch (std::invalid_argument const&) catch (std::invalid_argument const&)

View File

@@ -29,27 +29,32 @@ namespace beast {
/** A generic endpoint for log messages. */ /** A generic endpoint for log messages. */
class Journal class Journal
{ {
public:
class Sink;
private:
Sink* m_sink;
public: public:
/** Severity level of the message. */ /** Severity level of the message. */
enum Severity enum Severity
{ {
kLowestSeverity = 0, kAll = 0,
kTrace = kLowestSeverity,
kTrace = kAll,
kDebug, kDebug,
kInfo, kInfo,
kWarning, kWarning,
kError, kError,
kFatal, kFatal,
kDisabled kDisabled,
kNone = kDisabled
}; };
class Sink;
private:
Journal& operator= (Journal const& other); // disallowed
Sink* m_sink;
Severity m_level;
public:
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
/** Abstraction for the underlying message destination. */ /** Abstraction for the underlying message destination. */
@@ -82,7 +87,7 @@ public:
virtual void write (Severity level, std::string const& text) = 0; virtual void write (Severity level, std::string const& text) = 0;
private: private:
Severity m_severity; Severity m_level;
bool m_console; bool m_console;
}; };
@@ -103,23 +108,32 @@ public:
template <typename T> template <typename T>
ScopedStream (Stream const& stream, T const& t) ScopedStream (Stream const& stream, T const& t)
: m_sink (stream.sink()) : m_sink (stream.sink())
, m_severity (stream.severity()) , m_level (stream.severity())
, m_active (stream.active ())
{ {
m_ostream << t; if (active ())
m_ostream << t;
} }
ScopedStream (Stream const& stream, std::ostream& manip (std::ostream&)); ScopedStream (Stream const& stream,
std::ostream& manip (std::ostream&));
~ScopedStream (); ~ScopedStream ();
bool active () const
{ return m_active; }
std::ostringstream& ostream () const; std::ostringstream& ostream () const;
std::ostream& operator<< (std::ostream& manip (std::ostream&)) const; std::ostream& operator<< (
std::ostream& manip (std::ostream&)) const;
template <typename T> template <typename T>
std::ostream& operator<< (T const& t) const std::ostream& operator<< (T const& t) const
{ {
return m_ostream << t; if (active ())
m_ostream << t;
return m_ostream;
} }
private: private:
@@ -128,7 +142,8 @@ public:
ScopedStream& operator= (ScopedStream const&); // disallowed ScopedStream& operator= (ScopedStream const&); // disallowed
Sink& m_sink; Sink& m_sink;
Severity const m_severity; Severity const m_level;
bool const m_active;
std::ostringstream mutable m_ostream; std::ostringstream mutable m_ostream;
bool m_toOutputWindow; bool m_toOutputWindow;
}; };
@@ -138,11 +153,14 @@ public:
class Stream : public SafeBool <Stream> class Stream : public SafeBool <Stream>
{ {
public: public:
/** Construct a stream which produces no logging output. */ /** Create a stream which produces no output. */
Stream (); Stream ();
/** Construct a stream that writes to the Sink at the given Severity. */ /** Create stream that writes at the given level. */
Stream (Sink& sink, Severity severity); /** @{ */
Stream (Sink& sink, Severity level, bool active = true);
Stream (Stream const& stream, bool active);
/** @} */
/** Construct or copy another Stream. */ /** Construct or copy another Stream. */
/** @{ */ /** @{ */
@@ -175,24 +193,48 @@ public:
private: private:
Sink* m_sink; Sink* m_sink;
Severity m_severity; Severity m_level;
bool m_disabled;
}; };
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
/** Create a journal that writes to the null sink. */
Journal (); Journal ();
explicit Journal (Sink& sink);
/** Create a journal that writes to the specified sink. */
/** @{ */
explicit Journal (Sink& sink, Severity level = kAll);
/** Create a journal from another journal.
When specifying a new minimum severity level, the effective minimum
level will be the higher of the other journal and the specified value.
*/
/** @{ */
Journal (Journal const& other); Journal (Journal const& other);
Journal (Journal const& other, Severity level);
/** @} */
/** Destroy the journal. */
~Journal (); ~Journal ();
/** Returns the Sink associated with this Journal. */ /** Returns the Sink associated with this Journal. */
Sink& sink() const; Sink& sink() const;
/** Returns a stream for this sink, with the specified severity. */ /** Returns a stream for this sink, with the specified severity. */
Stream stream (Severity severity) const; Stream stream (Severity level) const;
/** Returns `true` if any message would be logged at this severity level. */ /** Returns `true` if any message would be logged at this severity level.
bool active (Severity severity) const; For a message to be logged, the severity must be at or above both
the journal's severity level and the sink's severity level.
*/
bool active (Severity level) const;
/** Returns this Journal's minimum severity level.
If the underlying sink has a higher threshold, there will still
be no output at that level.
*/
Severity severity () const;
/** Convenience sink streams for each severity level. */ /** Convenience sink streams for each severity level. */
Stream const trace; Stream const trace;
@@ -201,9 +243,6 @@ public:
Stream const warning; Stream const warning;
Stream const error; Stream const error;
Stream const fatal; Stream const fatal;
private:
Journal& operator= (Journal const& other); // disallowed
}; };
} }

View File

@@ -66,7 +66,7 @@ Journal::Sink& Journal::getNullSink ()
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Journal::Sink::Sink () Journal::Sink::Sink ()
: m_severity (kLowestSeverity) : m_level (kAll)
, m_console (false) , m_console (false)
{ {
} }
@@ -77,7 +77,7 @@ Journal::Sink::~Sink ()
bool Journal::Sink::active (Severity level) const bool Journal::Sink::active (Severity level) const
{ {
return level >= m_severity; return level >= m_level;
} }
bool Journal::Sink::console () const bool Journal::Sink::console () const
@@ -92,42 +92,56 @@ void Journal::Sink::console (bool output)
Journal::Severity Journal::Sink::severity () const Journal::Severity Journal::Sink::severity () const
{ {
return m_severity; return m_level;
} }
void Journal::Sink::severity (Severity level) void Journal::Sink::severity (Severity level)
{ {
m_severity = level; m_level = level;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Journal::ScopedStream::ScopedStream (Stream const& stream) Journal::ScopedStream::ScopedStream (Stream const& stream)
: m_sink (stream.sink()) : m_sink (stream.sink ())
, m_severity (stream.severity()) , m_level (stream.severity ())
, m_active (stream.active ())
{ {
init (); init ();
} }
Journal::ScopedStream::ScopedStream (ScopedStream const& other) Journal::ScopedStream::ScopedStream (ScopedStream const& other)
: m_sink (other.m_sink) : m_sink (other.m_sink)
, m_severity (other.m_severity) , m_level (other.m_level)
, m_active (other.m_active)
{ {
init (); init ();
} }
Journal::ScopedStream::ScopedStream (Stream const& stream, std::ostream& manip (std::ostream&)) Journal::ScopedStream::ScopedStream (
: m_sink (stream.sink()) Stream const& stream, std::ostream& manip (std::ostream&))
, m_severity (stream.severity()) : m_sink (stream.sink ())
, m_level (stream.severity ())
, m_active (stream.active ())
{ {
init (); init ();
m_ostream << manip; if (active ())
m_ostream << manip;
} }
Journal::ScopedStream::~ScopedStream () Journal::ScopedStream::~ScopedStream ()
{ {
if (! m_ostream.str().empty() && m_sink.active (m_severity)) if (active ())
m_sink.write (m_severity, m_ostream.str()); {
std::string const& s (m_ostream.str());
if (! s.empty ())
{
if (s == "\n")
m_sink.write (m_level, "");
else
m_sink.write (m_level, s);
}
}
} }
void Journal::ScopedStream::init () void Journal::ScopedStream::init ()
@@ -155,20 +169,30 @@ std::ostringstream& Journal::ScopedStream::ostream () const
Journal::Stream::Stream () Journal::Stream::Stream ()
: m_sink (&getNullSink ()) : m_sink (&getNullSink ())
, m_severity (kDisabled) , m_level (kDisabled)
, m_disabled (true)
{ {
} }
Journal::Stream::Stream (Sink& sink, Severity severity) Journal::Stream::Stream (Sink& sink, Severity level, bool active)
: m_sink (&sink) : m_sink (&sink)
, m_severity (severity) , m_level (level)
, m_disabled (! active)
{
bassert (level != kDisabled);
}
Journal::Stream::Stream (Stream const& stream, bool active)
: m_sink (&stream.sink ())
, m_level (stream.severity ())
, m_disabled (! active)
{ {
bassert (severity != kDisabled);
} }
Journal::Stream::Stream (Stream const& other) Journal::Stream::Stream (Stream const& other)
: m_sink (other.m_sink) : m_sink (other.m_sink)
, m_severity (other.m_severity) , m_level (other.m_level)
, m_disabled (other.m_disabled)
{ {
} }
@@ -179,12 +203,12 @@ Journal::Sink& Journal::Stream::sink () const
Journal::Severity Journal::Stream::severity () const Journal::Severity Journal::Stream::severity () const
{ {
return m_severity; return m_level;
} }
bool Journal::Stream::active () const bool Journal::Stream::active () const
{ {
return m_sink->active (m_severity); return ! m_disabled && m_sink->active (m_level);
} }
bool Journal::Stream::asBoolean () const bool Journal::Stream::asBoolean () const
@@ -195,11 +219,12 @@ bool Journal::Stream::asBoolean () const
Journal::Stream& Journal::Stream::operator= (Stream const& other) Journal::Stream& Journal::Stream::operator= (Stream const& other)
{ {
m_sink = other.m_sink; m_sink = other.m_sink;
m_severity = other.m_severity; m_level = other.m_level;
return *this; return *this;
} }
Journal::ScopedStream Journal::Stream::operator<< (std::ostream& manip (std::ostream&)) const Journal::ScopedStream Journal::Stream::operator<< (
std::ostream& manip (std::ostream&)) const
{ {
return ScopedStream (*this, manip); return ScopedStream (*this, manip);
} }
@@ -208,6 +233,7 @@ Journal::ScopedStream Journal::Stream::operator<< (std::ostream& manip (std::ost
Journal::Journal () Journal::Journal ()
: m_sink (&getNullSink()) : m_sink (&getNullSink())
, m_level (kDisabled)
, trace (stream (kTrace)) , trace (stream (kTrace))
, debug (stream (kDebug)) , debug (stream (kDebug))
, info (stream (kInfo)) , info (stream (kInfo))
@@ -217,8 +243,9 @@ Journal::Journal ()
{ {
} }
Journal::Journal (Sink& sink) Journal::Journal (Sink& sink, Severity level)
: m_sink (&sink) : m_sink (&sink)
, m_level (level)
, trace (stream (kTrace)) , trace (stream (kTrace))
, debug (stream (kDebug)) , debug (stream (kDebug))
, info (stream (kInfo)) , info (stream (kInfo))
@@ -230,6 +257,19 @@ Journal::Journal (Sink& sink)
Journal::Journal (Journal const& other) Journal::Journal (Journal const& other)
: m_sink (other.m_sink) : m_sink (other.m_sink)
, m_level (other.m_level)
, trace (stream (kTrace))
, debug (stream (kDebug))
, info (stream (kInfo))
, warning (stream (kWarning))
, error (stream (kError))
, fatal (stream (kFatal))
{
}
Journal::Journal (Journal const& other, Severity level)
: m_sink (other.m_sink)
, m_level (std::max (other.m_level, level))
, trace (stream (kTrace)) , trace (stream (kTrace))
, debug (stream (kDebug)) , debug (stream (kDebug))
, info (stream (kInfo)) , info (stream (kInfo))
@@ -248,15 +288,23 @@ Journal::Sink& Journal::sink() const
return *m_sink; return *m_sink;
} }
Journal::Stream Journal::stream (Severity severity) const Journal::Stream Journal::stream (Severity level) const
{ {
return Stream (*m_sink, severity); return Stream (*m_sink, level, level >= m_level);
} }
bool Journal::active (Severity severity) const bool Journal::active (Severity level) const
{ {
bassert (severity != kDisabled); if (level == kDisabled)
return m_sink->active (severity); return false;
if (level < m_level)
return false;
return m_sink->active (level);
}
Journal::Severity Journal::severity () const
{
return m_level;
} }
} }

View File

@@ -30,11 +30,6 @@
#endif #endif
#include <boost/version.hpp> #include <boost/version.hpp>
#if BOOST_VERSION > 105499
# error "This hasnt been tested with boost versions above 1.54"
#endif
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/bind/arg.hpp> #include <boost/bind/arg.hpp>