early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,328 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// Addition to STL algorithms
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_ALGORITHM_HPP
#define BOOST_TEST_UTILS_ALGORITHM_HPP
#include <boost/test/detail/config.hpp>
// STL
#include <utility>
#include <algorithm> // std::find
#include <functional> // std::bind1st or std::bind
#include <boost/test/detail/suppress_warnings.hpp>
#ifdef BOOST_NO_CXX98_BINDERS
#define BOOST_TEST_BIND1ST(F,A) std::bind( (F), (A), std::placeholders::_1 )
#else
#define BOOST_TEST_BIND1ST(F,A) std::bind1st( (F), (A) )
#endif
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace utils {
/// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
/// of iterators, first pointing to the mismatch position in first collection, second iterator in second one
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template <class InputIter1, class InputIter2>
inline std::pair<InputIter1, InputIter2>
mismatch( InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2 )
{
while( first1 != last1 && first2 != last2 && *first1 == *first2 ) {
++first1;
++first2;
}
return std::pair<InputIter1, InputIter2>(first1, first2);
}
//____________________________________________________________________________//
/// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
/// of iterators, first pointing to the mismatch position in first collection, second iterator in second one. This algorithms
/// uses supplied predicate for collection elements comparison
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template <class InputIter1, class InputIter2, class Predicate>
inline std::pair<InputIter1, InputIter2>
mismatch( InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2,
Predicate pred )
{
while( first1 != last1 && first2 != last2 && pred( *first1, *first2 ) ) {
++first1;
++first2;
}
return std::pair<InputIter1, InputIter2>(first1, first2);
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for first element that does not belong a second one
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1
find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
while( first1 != last1 ) {
if( std::find( first2, last2, *first1 ) == last2 )
break;
++first1;
}
return first1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for first element that does not satisfy binary
/// predicate in conjunction will any element in second collection
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template<class ForwardIterator1, class ForwardIterator2, class Predicate>
inline ForwardIterator1
find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
Predicate pred )
{
while( first1 != last1 ) {
if( std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *first1 ) ) == last2 )
break;
++first1;
}
return first1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that belongs to a second one
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class BidirectionalIterator1, class ForwardIterator2>
inline BidirectionalIterator1
find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
if( first1 == last1 || first2 == last2 )
return last1;
BidirectionalIterator1 it1 = last1;
while( --it1 != first1 && std::find( first2, last2, *it1 ) == last2 ) {}
return it1 == first1 && std::find( first2, last2, *it1 ) == last2 ? last1 : it1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that satisfy binary
/// predicate in conjunction will at least one element in second collection
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
inline BidirectionalIterator1
find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
Predicate pred )
{
if( first1 == last1 || first2 == last2 )
return last1;
BidirectionalIterator1 it1 = last1;
while( --it1 != first1 && std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *it1 ) ) == last2 ) {}
return it1 == first1 && std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *it1 ) ) == last2 ? last1 : it1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that does not belong to a second one
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class BidirectionalIterator1, class ForwardIterator2>
inline BidirectionalIterator1
find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
if( first1 == last1 || first2 == last2 )
return last1;
BidirectionalIterator1 it1 = last1;
while( --it1 != first1 && std::find( first2, last2, *it1 ) != last2 ) {}
return it1 == first1 && std::find( first2, last2, *it1 ) != last2 ? last1 : it1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that does not satisfy binary
/// predicate in conjunction will any element in second collection
///
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
inline BidirectionalIterator1
find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
Predicate pred )
{
if( first1 == last1 || first2 == last2 )
return last1;
BidirectionalIterator1 it1 = last1;
while( --it1 != first1 && std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *it1 ) ) != last2 ) {}
return it1 == first1 && std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *it1 ) ) == last2 ? last1 : it1;
}
//____________________________________________________________________________//
/// @brief This algorithm replaces all occurrences of a set of substrings by another substrings
///
/// @param str - string of operation
/// @param first1 - iterator to the beginning of the substrings to replace
/// @param last1 - iterator to the end of the substrings to replace
/// @param first2 - iterator to the beginning of the substrings to replace with
/// @param last2 - iterator to the end of the substrings to replace with
template<class StringClass, class ForwardIterator>
inline StringClass
replace_all_occurrences_of( StringClass str,
ForwardIterator first1, ForwardIterator last1,
ForwardIterator first2, ForwardIterator last2)
{
for(; first1 != last1 && first2 != last2; ++first1, ++first2) {
std::size_t found = str.find( *first1 );
while( found != StringClass::npos ) {
str.replace(found, first1->size(), *first2 );
found = str.find( *first1, found + first2->size() );
}
}
return str;
}
/// @brief This algorithm replaces all occurrences of a string with basic wildcards
/// with another (optionally containing wildcards as well).
///
/// @param str - string to transform
/// @param it_string_to_find - iterator to the beginning of the substrings to replace
/// @param it_string_to_find_end - iterator to the end of the substrings to replace
/// @param it_string_to_replace - iterator to the beginning of the substrings to replace with
/// @param it_string_to_replace_end - iterator to the end of the substrings to replace with
///
/// The wildcard is the symbol '*'. Only a unique wildcard per string is supported. The replacement
/// string may also contain a wildcard, in which case it is considered as a placeholder to the content
/// of the wildcard in the source string.
/// Example:
/// - In order to replace the occurrences of @c 'time=\"some-variable-value\"' to a constant string,
/// one may use @c 'time=\"*\"' as the string to search for, and 'time=\"0.0\"' as the replacement string.
/// - In order to replace the occurrences of 'file.cpp(XX)' per 'file.cpp:XX', where XX is a variable to keep,
/// on may use @c 'file.cpp(*)' as the string to search for, and 'file.cpp:*' as the replacement string.
template<class StringClass, class ForwardIterator>
inline StringClass
replace_all_occurrences_with_wildcards(
StringClass str,
ForwardIterator it_string_to_find, ForwardIterator it_string_to_find_end,
ForwardIterator it_string_to_replace, ForwardIterator it_string_to_replace_end)
{
for(; it_string_to_find != it_string_to_find_end && it_string_to_replace != it_string_to_replace_end;
++it_string_to_find, ++ it_string_to_replace) {
std::size_t wildcard_pos = it_string_to_find->find("*");
if(wildcard_pos == StringClass::npos) {
ForwardIterator it_to_find_current_end(it_string_to_find);
ForwardIterator it_to_replace_current_end(it_string_to_replace);
str = replace_all_occurrences_of(
str,
it_string_to_find, ++it_to_find_current_end,
it_string_to_replace, ++it_to_replace_current_end);
continue;
}
std::size_t wildcard_pos_replace = it_string_to_replace->find("*");
std::size_t found_begin = str.find( it_string_to_find->substr(0, wildcard_pos) );
while( found_begin != StringClass::npos ) {
std::size_t found_end = str.find(it_string_to_find->substr(wildcard_pos+1), found_begin + wildcard_pos + 1); // to simplify
if( found_end != StringClass::npos ) {
if( wildcard_pos_replace == StringClass::npos ) {
StringClass replace_content = *it_string_to_replace;
str.replace(
found_begin,
found_end + (it_string_to_find->size() - wildcard_pos - 1 ) - found_begin,
replace_content);
} else {
StringClass replace_content =
it_string_to_replace->substr(0, wildcard_pos_replace)
+ str.substr(found_begin + wildcard_pos,
found_end - found_begin - wildcard_pos)
+ it_string_to_replace->substr(wildcard_pos_replace+1) ;
str.replace(
found_begin,
found_end + (it_string_to_find->size() - wildcard_pos - 1 ) - found_begin,
replace_content);
}
}
// may adapt the restart to the replacement and be more efficient
found_begin = str.find( it_string_to_find->substr(0, wildcard_pos), found_begin + 1 );
}
}
return str;
}
} // namespace utils
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_ALGORITHM_HPP

View File

@@ -0,0 +1,39 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : overloadable assignment
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_ASSIGN_OP_HPP
#define BOOST_TEST_UTILS_ASSIGN_OP_HPP
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** generic assign operator ************** //
// ************************************************************************** //
// generic
template<typename T,typename S>
inline void
assign_op( T& t, S const& s, long )
{
t = s;
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_UTILS_ASSIGN_OP_HPP

View File

@@ -0,0 +1,787 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : class basic_cstring wraps C string and provide std_string like
// interface
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp>
#include <boost/test/utils/basic_cstring/bcs_char_traits.hpp>
// Boost
#include <boost/type_traits/remove_cv.hpp>
// STL
#include <string>
#if defined(BOOST_TEST_STRING_VIEW)
#include <string_view>
#endif
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** basic_cstring ************** //
// ************************************************************************** //
template<typename CharT>
class BOOST_SYMBOL_VISIBLE basic_cstring {
typedef basic_cstring<CharT> self_type;
public:
// Subtypes
typedef ut_detail::bcs_char_traits<CharT> traits_type;
typedef typename traits_type::std_string std_string;
typedef CharT value_type;
typedef typename remove_cv<value_type>::type value_ret_type;
typedef value_type* pointer;
typedef value_type const* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef value_type const* const_iterator;
typedef value_type* iterator;
// !! should also present reverse_iterator, const_reverse_iterator
#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) && !defined(__DCC__)
BOOST_STATIC_CONSTANT(size_type, npos = static_cast<size_type>(-1));
#else
// IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes.
// But size_type is 8 bytes in 64bit mode.
static const size_type npos = -1 ;
#endif
static pointer null_str();
// Constructors; default copy constructor is generated by compiler
basic_cstring();
basic_cstring( basic_cstring const & );
basic_cstring( std_string const& s );
basic_cstring( pointer s );
template<typename LenType>
basic_cstring( pointer s, LenType len ) : m_begin( s ), m_end( m_begin + len ) {}
basic_cstring( pointer first, pointer last );
// data access methods
value_ret_type operator[]( size_type index ) const;
value_ret_type at( size_type index ) const;
// size operators
size_type size() const;
bool is_empty() const;
void clear();
void resize( size_type new_len );
// !! only for STL container conformance use is_empty instead
bool empty() const;
// Trimming
self_type& trim_right( size_type trim_size );
self_type& trim_left( size_type trim_size );
self_type& trim_right( iterator it );
self_type& trim_left( iterator it );
#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(800))
self_type& trim_left( self_type exclusions = self_type() ) ;
self_type& trim_right( self_type exclusions = self_type() ) ;
self_type& trim( self_type exclusions = self_type() ) ;
#else
// VA C++/XL C++ v6 and v8 has in this case a problem with the default arguments.
self_type& trim_left( self_type exclusions );
self_type& trim_right( self_type exclusions );
self_type& trim( self_type exclusions );
self_type& trim_left() { return trim_left( self_type() ); }
self_type& trim_right() { return trim_right( self_type() ); }
self_type& trim() { return trim( self_type() ); }
#endif
// Assignment operators
basic_cstring& operator=( self_type const& s );
basic_cstring& operator=( std_string const& s );
basic_cstring& operator=( pointer s );
template<typename CharT2>
basic_cstring& assign( basic_cstring<CharT2> const& s )
{
return *this = basic_cstring<CharT>( s.begin(), s.end() );
}
template<typename PosType, typename LenType>
basic_cstring& assign( self_type const& s, PosType pos, LenType len )
{
return *this = self_type( s.m_begin + pos, len );
}
basic_cstring& assign( std_string const& s );
template<typename PosType, typename LenType>
basic_cstring& assign( std_string const& s, PosType pos, LenType len )
{
return *this = self_type( s.c_str() + pos, len );
}
basic_cstring& assign( pointer s );
template<typename LenType>
basic_cstring& assign( pointer s, LenType len )
{
return *this = self_type( s, len );
}
basic_cstring& assign( pointer f, pointer l );
// swapping
void swap( self_type& s );
// Iterators
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
// !! should have rbegin, rend
// substring search operation
size_type find( basic_cstring ) const;
size_type rfind( basic_cstring ) const;
self_type substr( size_type beg_index, size_type end_index = npos ) const;
private:
static self_type default_trim_ex();
// Data members
iterator m_begin;
iterator m_end;
static CharT null;
};
// ************************************************************************** //
// ************** cstring_string_view_helper ************** //
// ************************************************************************** //
#if defined(BOOST_TEST_STRING_VIEW)
// Helper for instanciating a subclass of cstring using a string_view. We do not
// change the API of cstring using BOOST_TEST_STRING_VIEW as the code should remain
// compatible between boost.test and test module using different compiler options.
//! @internal
template <class CharT, class string_view_t = std::basic_string_view<CharT>>
class BOOST_SYMBOL_VISIBLE stringview_cstring_helper : public basic_cstring<CharT> {
public:
stringview_cstring_helper(string_view_t const& sv)
: basic_cstring<CharT>(const_cast<CharT*>(sv.data()), sv.size())
{}
};
#endif
// ************************************************************************** //
// ************** basic_cstring::impl ************** //
// ************************************************************************** //
//____________________________________________________________________________//
template<typename CharT>
CharT basic_cstring<CharT>::null = 0;
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::pointer
basic_cstring<CharT>::null_str()
{
return &null;
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring()
: m_begin( null_str() )
, m_end( m_begin )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring(basic_cstring const & s)
: m_begin( s.m_begin )
, m_end( s.m_end )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( std_string const& s )
: m_begin( s.c_str() )
, m_end( m_begin + s.size() )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( pointer s )
: m_begin( s ? s : null_str() )
, m_end ( m_begin + (s ? traits_type::length( s ) : 0 ) )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( pointer first, pointer last )
: m_begin( first )
, m_end( last )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
basic_cstring<CharT>::operator[]( size_type index ) const
{
return m_begin[index];
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
basic_cstring<CharT>::at( size_type index ) const
{
if( m_begin + index >= m_end )
return static_cast<value_type>(0);
return m_begin[index];
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::size() const
{
return static_cast<size_type>(m_end - m_begin);
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
basic_cstring<CharT>::is_empty() const
{
return m_end == m_begin;
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
basic_cstring<CharT>::empty() const
{
return is_empty();
}
//____________________________________________________________________________//
template<typename CharT>
inline void
basic_cstring<CharT>::clear()
{
m_begin = m_end;
}
//____________________________________________________________________________//
template<typename CharT>
inline void
basic_cstring<CharT>::resize( size_type new_len )
{
if( m_begin + new_len < m_end )
m_end = m_begin + new_len;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_left( size_type trim_size )
{
m_begin += trim_size;
if( m_end <= m_begin )
clear();
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_left( iterator it )
{
m_begin = it;
if( m_end <= m_begin )
clear();
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_left( basic_cstring exclusions )
{
if( exclusions.is_empty() )
exclusions = default_trim_ex();
iterator it;
for( it = begin(); it != end(); ++it ) {
if( traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) )
break;
}
return trim_left( it );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_right( size_type trim_size )
{
m_end -= trim_size;
if( m_end <= m_begin )
clear();
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_right( iterator it )
{
m_end = it;
if( m_end <= m_begin )
clear();
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_right( basic_cstring exclusions )
{
if(!size()) {
return *this;
}
if( exclusions.is_empty() )
exclusions = default_trim_ex();
iterator it = end();
do {
--it;
if( self_type::traits_type::find( exclusions.begin(), exclusions.size(), *it ) == reinterpret_cast<pointer>(0) )
break;
} while(it != begin());
return trim_right( it + 1 );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim( basic_cstring exclusions )
{
trim_left( exclusions );
trim_right( exclusions );
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::operator=( basic_cstring<CharT> const& s )
{
m_begin = s.m_begin;
m_end = s.m_end;
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::operator=( std_string const& s )
{
return *this = self_type( s );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::operator=( pointer s )
{
return *this = self_type( s );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( std_string const& s )
{
return *this = self_type( s );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( pointer s )
{
return *this = self_type( s );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( pointer f, pointer l )
{
return *this = self_type( f, l );
}
//____________________________________________________________________________//
template<typename CharT>
inline void
basic_cstring<CharT>::swap( basic_cstring<CharT>& s )
{
// do not want to include alogrithm
pointer tmp1 = m_begin;
pointer tmp2 = m_end;
m_begin = s.m_begin;
m_end = s.m_end;
s.m_begin = tmp1;
s.m_end = tmp2;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::iterator
basic_cstring<CharT>::begin()
{
return m_begin;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::const_iterator
basic_cstring<CharT>::begin() const
{
return m_begin;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::iterator
basic_cstring<CharT>::end()
{
return m_end;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::const_iterator
basic_cstring<CharT>::end() const
{
return m_end;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::find( basic_cstring<CharT> str ) const
{
if( str.is_empty() || str.size() > size() )
return static_cast<size_type>(npos);
const_iterator it = begin();
const_iterator last = end() - str.size() + 1;
while( it != last ) {
if( traits_type::compare( it, str.begin(), str.size() ) == 0 )
break;
++it;
}
return it == last ? npos : static_cast<size_type>(it - begin());
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::rfind( basic_cstring<CharT> str ) const
{
if( str.is_empty() || str.size() > size() )
return static_cast<size_type>(npos);
const_iterator it = end() - str.size();
const_iterator last = begin()-1;
while( it != last ) {
if( traits_type::compare( it, str.begin(), str.size() ) == 0 )
break;
--it;
}
return it == last ? static_cast<size_type>(npos) : static_cast<size_type>(it - begin());
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>
basic_cstring<CharT>::substr( size_type beg_index, size_type end_index ) const
{
return beg_index > size()
? self_type()
: end_index > size()
? self_type( m_begin + beg_index, m_end )
: self_type( m_begin + beg_index, m_begin + end_index );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>
basic_cstring<CharT>::default_trim_ex()
{
static CharT ws[3] = { CharT(' '), CharT('\t'), CharT('\n') }; // !! wide case
return self_type( ws, 3 );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** comparison operators ************** //
// ************************************************************************** //
template<typename CharT1,typename CharT2>
inline bool
operator==( basic_cstring<CharT1> const& s1, basic_cstring<CharT2> const& s2 )
{
typedef typename basic_cstring<CharT1>::traits_type traits_type;
return s1.size() == s2.size() &&
traits_type::compare( s1.begin(), s2.begin(), s1.size() ) == 0;
}
//____________________________________________________________________________//
template<typename CharT1,typename CharT2>
inline bool
operator==( basic_cstring<CharT1> const& s1, CharT2* s2 )
{
#if !defined(__DMC__)
return s1 == basic_cstring<CharT2>( s2 );
#else
return s1 == basic_cstring<CharT2 const>( s2 );
#endif
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator==( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
{
return s1 == basic_cstring<CharT>( s2 );
}
//____________________________________________________________________________//
template<typename CharT1,typename CharT2>
inline bool
operator==( CharT1* s2, basic_cstring<CharT2> const& s1 )
{
return s1 == s2;
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator==( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
{
return s1 == s2;
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( basic_cstring<CharT> const& s1, CharT* s2 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( CharT* s2, basic_cstring<CharT> const& s1 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( basic_cstring<CharT> const& s1, basic_cstring<CharT> const& s2 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** first_char ************** //
// ************************************************************************** //
template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
first_char( basic_cstring<CharT> source )
{
typedef typename basic_cstring<CharT>::value_ret_type res_type;
return source.is_empty() ? static_cast<res_type>(0) : *source.begin();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** last_char ************** //
// ************************************************************************** //
template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
last_char( basic_cstring<CharT> source )
{
typedef typename basic_cstring<CharT>::value_ret_type res_type;
return source.is_empty() ? static_cast<res_type>(0) : *(source.end()-1);
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** assign_op ************** //
// ************************************************************************** //
template<typename CharT1, typename CharT2>
inline void
assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> src, int )
{
target.assign( src.begin(), src.size() );
}
//____________________________________________________________________________//
template<typename CharT1, typename CharT2>
inline std::basic_string<CharT1>&
operator+=( std::basic_string<CharT1>& target, basic_cstring<CharT2> const& str )
{
target.append( str.begin(), str.end() );
return target;
}
//____________________________________________________________________________//
template<typename CharT1, typename CharT2>
inline std::basic_string<CharT1>
operator+( std::basic_string<CharT1> const& lhs, basic_cstring<CharT2> const& rhs )
{
std::basic_string<CharT1> res( lhs );
res.append( rhs.begin(), rhs.end() );
return res;
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_BASIC_CSTRING_HPP

View File

@@ -0,0 +1,46 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : basic_cstring class wrap C string and provide std_string like
// interface
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
#include <boost/test/detail/config.hpp>
namespace boost {
namespace unit_test {
template<typename CharT> class BOOST_SYMBOL_VISIBLE basic_cstring;
typedef basic_cstring<char const> const_string;
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590041))
typedef const_string literal_string;
#else
typedef const_string const literal_string;
#endif
typedef char const* const c_literal_string;
#if defined(BOOST_TEST_STRING_VIEW)
template <class CharT, class string_view_t>
class BOOST_SYMBOL_VISIBLE stringview_cstring_helper;
#endif
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP

View File

@@ -0,0 +1,150 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : generic char traits class; wraps std::char_traits
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP
#define BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP
// Boost
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/test/detail/config.hpp>
#include <boost/type_traits/add_const.hpp>
// STL
#include <string> // std::char_traits
#include <cstddef> // std::size_t
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace ut_detail {
template<typename CharT> struct bcs_base_char { typedef CharT type; };
template<> struct bcs_base_char<char const> { typedef char type; };
template<> struct bcs_base_char<unsigned char> { typedef char type; };
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
template<> struct bcs_base_char<unsigned char const> { typedef char type; };
#endif
template<> struct bcs_base_char<wchar_t const> { typedef wchar_t type; };
// ************************************************************************** //
// ************** bcs_char_traits ************** //
// ************************************************************************** //
template<typename CharT>
struct bcs_char_traits_impl
{
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
typedef CharT const const_char;
#else
typedef typename boost::add_const<CharT>::type const_char;
#endif
static bool eq( CharT c1, CharT c2 )
{
return c1 == c2;
}
static bool lt( CharT c1, CharT c2 )
{
return c1 < c2;
}
static int compare( const_char* cstr1, const_char* cstr2, std::size_t n )
{
while( n > 0 ) {
if( !eq( *cstr1, *cstr2 ) )
return lt( *cstr1, *cstr2 ) ? -1 : 1;
++cstr1;
++cstr2;
--n;
}
return 0;
}
static std::size_t length( const_char* cstr )
{
const_char null_char = CharT();
const_char* ptr = cstr;
while( !eq( *ptr, null_char ) )
++ptr;
return ptr - cstr;
}
static const_char* find( const_char* s, std::size_t n, CharT c )
{
while( n > 0 ) {
if( eq( *s, c ) )
return s;
++s;
--n;
}
return 0;
}
};
#ifdef BOOST_CLASSIC_IOSTREAMS
template<typename CharT>
struct char_traits_with_find : std::string_char_traits<CharT> {
static CharT const* find( CharT const* s, std::size_t n, CharT c )
{
while( n > 0 ) {
if( eq( *s, c ) )
return s;
++s;
--n;
}
return 0;
}
};
template<> struct bcs_char_traits_impl<char> : public char_traits_with_find<char> {};
template<> struct bcs_char_traits_impl<wchar_t> : public char_traits_with_find<wchar_t> {};
#else
template<> struct bcs_char_traits_impl<char> : public std::char_traits<char> {};
template<> struct bcs_char_traits_impl<wchar_t> : public std::char_traits<wchar_t> {};
#endif
template<typename CharT>
class bcs_char_traits : public bcs_char_traits_impl<CharT> {
typedef typename ut_detail::bcs_base_char<CharT>::type the_base_char;
public:
#ifdef BOOST_CLASSIC_IOSTREAMS
typedef std::basic_string<the_base_char, std::string_char_traits<the_base_char> > std_string;
#else
typedef std::basic_string<the_base_char, std::char_traits<the_base_char> > std_string;
#endif
};
} // namespace ut_detail
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP

View File

@@ -0,0 +1,151 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : class basic_cstring comparisons implementation
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_COMPARE_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_COMPARE_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// STL
#include <functional>
#include <cctype>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
# if defined(BOOST_NO_STDC_NAMESPACE) && !BOOST_WORKAROUND(BOOST_BORLANDC, <= 0x570)
namespace std { using ::toupper; }
# endif
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** case_ins_compare ************** //
// ************************************************************************** //
namespace ut_detail {
template<class CharT>
struct case_ins
{
static bool eq( CharT c1, CharT c2 ) { return (std::toupper)( c1 ) == (std::toupper)( c2 ); }
static bool lt( CharT c1, CharT c2 ) { return (std::toupper)( c1 ) < (std::toupper)( c2 ); }
static int compare( CharT const* s1, CharT const* s2, std::size_t n )
{
for( std::size_t i = 0; i < n; ++i ) {
if( !eq( s1[i], s2[i] ) )
return lt( s1[i], s2[i] ) ? -1 : 1;
}
return 0;
}
};
} // namespace ut_detail
// ************************************************************************** //
// ************** case_ins_eq ************** //
// ************************************************************************** //
template<class CharT>
inline bool
case_ins_eq( basic_cstring<CharT> x, basic_cstring<CharT> y )
{
return x.size() == y.size() && ut_detail::case_ins<CharT>::compare( x.begin(), y.begin(), x.size() ) == 0;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** case_ins_less ************** //
// ************************************************************************** //
template<class CharT>
class case_ins_less
{
public:
typedef bool result_type;
typedef basic_cstring<CharT> first_argument_type;
typedef basic_cstring<CharT> second_argument_type;
bool operator()( basic_cstring<CharT> x, basic_cstring<CharT> y ) const
{
return x.size() != y.size()
? x.size() < y.size()
: ut_detail::case_ins<CharT>::compare( x.begin(), y.begin(), x.size() ) < 0;
}
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** operators <,> ************** //
// ************************************************************************** //
template<class CharT>
inline bool
operator <( boost::unit_test::basic_cstring<CharT> const& x,
boost::unit_test::basic_cstring<CharT> const& y )
{
typedef typename boost::unit_test::basic_cstring<CharT>::traits_type traits_type;
return x.size() != y.size()
? x.size() < y.size()
: traits_type::compare( x.begin(), y.begin(), x.size() ) < 0;
}
//____________________________________________________________________________//
template<class CharT>
inline bool
operator <=( boost::unit_test::basic_cstring<CharT> const& x,
boost::unit_test::basic_cstring<CharT> const& y )
{
return !(y < x);
}
//____________________________________________________________________________//
template<class CharT>
inline bool
operator >( boost::unit_test::basic_cstring<CharT> const& x,
boost::unit_test::basic_cstring<CharT> const& y )
{
return y < x;
}
//____________________________________________________________________________//
template<class CharT>
inline bool
operator >=( boost::unit_test::basic_cstring<CharT> const& x,
boost::unit_test::basic_cstring<CharT> const& y )
{
return !(x < y);
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_BASIC_CSTRING_COMPARE_HPP_071894GER

View File

@@ -0,0 +1,73 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : basic_cstring i/o implementation
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// STL
#include <iosfwd>
#include <string>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
#ifdef BOOST_CLASSIC_IOSTREAMS
template<typename CharT>
inline std::ostream&
operator<<( std::ostream& os, basic_cstring<CharT> const& str )
{
typedef typename ut_detail::bcs_base_char<CharT>::type char_type;
char_type const* const beg = reinterpret_cast<char_type const* const>( str.begin() );
char_type const* const end = reinterpret_cast<char_type const* const>( str.end() );
os << std::basic_string<char_type>( beg, end - beg );
return os;
}
#else
template<typename CharT1, typename Tr,typename CharT2>
inline std::basic_ostream<CharT1,Tr>&
operator<<( std::basic_ostream<CharT1,Tr>& os, basic_cstring<CharT2> const& str )
{
CharT1 const* const beg = reinterpret_cast<CharT1 const*>( str.begin() ); // !!
CharT1 const* const end = reinterpret_cast<CharT1 const*>( str.end() );
os << std::basic_string<CharT1,Tr>( beg, end - beg );
return os;
}
#endif
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_BASIC_CSTRING_IO_HPP_071894GER

View File

@@ -0,0 +1,195 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : simple facility that mimmic notion of read-only read-write
// properties in C++ classes. Original idea by Henrik Ravn.
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP
#define BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
// Boost
#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
#include <boost/preprocessor/seq/for_each.hpp>
#endif
#include <boost/call_traits.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/utility/addressof.hpp>
// STL
#include <iosfwd>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** class_property ************** //
// ************************************************************************** //
template<class PropertyType>
class class_property {
protected:
typedef typename call_traits<PropertyType>::const_reference read_access_t;
typedef typename call_traits<PropertyType>::param_type write_param_t;
typedef typename add_pointer<typename add_const<PropertyType>::type>::type address_res_t;
public:
// Constructor
class_property() : value( PropertyType() ) {}
explicit class_property( write_param_t init_value )
: value( init_value ) {}
// Access methods
operator read_access_t() const { return value; }
read_access_t get() const { return value; }
bool operator!() const { return !value; }
address_res_t operator&() const { return &value; }
// Data members
#ifndef BOOST_TEST_NO_PROTECTED_USING
protected:
#endif
PropertyType value;
};
//____________________________________________________________________________//
#ifdef BOOST_CLASSIC_IOSTREAMS
template<class PropertyType>
inline std::ostream&
operator<<( std::ostream& os, class_property<PropertyType> const& p )
#else
template<typename CharT1, typename Tr,class PropertyType>
inline std::basic_ostream<CharT1,Tr>&
operator<<( std::basic_ostream<CharT1,Tr>& os, class_property<PropertyType> const& p )
#endif
{
return os << p.get();
}
//____________________________________________________________________________//
#define DEFINE_PROPERTY_FREE_BINARY_OPERATOR( op ) \
template<class PropertyType> \
inline bool \
operator op( PropertyType const& lhs, class_property<PropertyType> const& rhs ) \
{ \
return lhs op rhs.get(); \
} \
template<class PropertyType> \
inline bool \
operator op( class_property<PropertyType> const& lhs, PropertyType const& rhs ) \
{ \
return lhs.get() op rhs; \
} \
template<class PropertyType> \
inline bool \
operator op( class_property<PropertyType> const& lhs, \
class_property<PropertyType> const& rhs ) \
{ \
return lhs.get() op rhs.get(); \
} \
/**/
DEFINE_PROPERTY_FREE_BINARY_OPERATOR( == )
DEFINE_PROPERTY_FREE_BINARY_OPERATOR( != )
#undef DEFINE_PROPERTY_FREE_BINARY_OPERATOR
// ************************************************************************** //
// ************** readonly_property ************** //
// ************************************************************************** //
template<class PropertyType>
class readonly_property : public class_property<PropertyType> {
typedef class_property<PropertyType> base_prop;
typedef typename base_prop::address_res_t arrow_res_t;
protected:
typedef typename base_prop::write_param_t write_param_t;
public:
// Constructor
readonly_property() {}
explicit readonly_property( write_param_t init_value ) : base_prop( init_value ) {}
// access methods
arrow_res_t operator->() const { return boost::addressof( base_prop::value ); }
};
//____________________________________________________________________________//
#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
#define BOOST_READONLY_PROPERTY( property_type, friends ) boost::unit_test::readwrite_property<property_type >
#else
#define BOOST_READONLY_PROPERTY_DECLARE_FRIEND(r, data, elem) friend class elem;
#define BOOST_READONLY_PROPERTY( property_type, friends ) \
class BOOST_JOIN( readonly_property, __LINE__ ) \
: public boost::unit_test::readonly_property<property_type > { \
typedef boost::unit_test::readonly_property<property_type > base_prop; \
BOOST_PP_SEQ_FOR_EACH( BOOST_READONLY_PROPERTY_DECLARE_FRIEND, ' ', friends ) \
typedef base_prop::write_param_t write_param_t; \
public: \
BOOST_JOIN( readonly_property, __LINE__ )() {} \
explicit BOOST_JOIN( readonly_property, __LINE__ )( write_param_t init_v ) \
: base_prop( init_v ) {} \
} \
/**/
#endif
// ************************************************************************** //
// ************** readwrite_property ************** //
// ************************************************************************** //
template<class PropertyType>
class readwrite_property : public class_property<PropertyType> {
typedef class_property<PropertyType> base_prop;
typedef typename add_pointer<PropertyType>::type arrow_res_t;
typedef typename base_prop::address_res_t const_arrow_res_t;
typedef typename base_prop::write_param_t write_param_t;
public:
readwrite_property() : base_prop() {}
explicit readwrite_property( write_param_t init_value ) : base_prop( init_value ) {}
// access methods
void set( write_param_t v ) { base_prop::value = v; }
arrow_res_t operator->() { return boost::addressof( base_prop::value ); }
const_arrow_res_t operator->() const { return boost::addressof( base_prop::value ); }
#ifndef BOOST_TEST_NO_PROTECTED_USING
using base_prop::value;
#endif
};
//____________________________________________________________________________//
} // unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#undef BOOST_TEST_NO_PROTECTED_USING
#endif // BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP

View File

@@ -0,0 +1,61 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : simple helpers for creating cusom output manipulators
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_CUSTOM_MANIP_HPP
#define BOOST_TEST_UTILS_CUSTOM_MANIP_HPP
// STL
#include <iosfwd>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace utils {
// ************************************************************************** //
// ************** custom manipulators helpers ************** //
// ************************************************************************** //
template<typename Manip>
struct custom_printer {
explicit custom_printer( std::ostream& ostr ) : m_ostr( &ostr ) {}
std::ostream& operator*() const { return *m_ostr; }
private:
std::ostream* const m_ostr;
};
//____________________________________________________________________________//
template<typename Uniq> struct custom_manip {};
//____________________________________________________________________________//
template<typename Uniq>
inline custom_printer<custom_manip<Uniq> >
operator<<( std::ostream& ostr, custom_manip<Uniq> const& ) { return custom_printer<custom_manip<Uniq> >( ostr ); }
//____________________________________________________________________________//
} // namespace utils
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_CUSTOM_MANIP_HPP

View File

@@ -0,0 +1,315 @@
// (C) Copyright Eric Niebler 2004-2005
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : this is an abridged version of an excelent BOOST_FOREACH facility
// presented by Eric Niebler. I am so fond of it so I can't wait till it
// going to be accepted into Boost. Also I need version with less number of dependencies
// and more portable. This version doesn't support rvalues and will reeveluate it's
// parameters, but should be good enough for my purposes.
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_FOREACH_HPP
#define BOOST_TEST_UTILS_FOREACH_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
// Boost
#include <boost/type.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace for_each {
// ************************************************************************** //
// ************** static_any ************** //
// ************************************************************************** //
struct static_any_base
{
operator bool() const { return false; }
};
//____________________________________________________________________________//
template<typename Iter>
struct static_any : static_any_base
{
static_any( Iter const& t ) : m_it( t ) {}
mutable Iter m_it;
};
//____________________________________________________________________________//
typedef static_any_base const& static_any_t;
//____________________________________________________________________________//
template<typename Iter>
inline Iter&
static_any_cast( static_any_t a, Iter* = 0 )
{
return static_cast<Iter&>( static_cast<static_any<Iter> const&>( a ).m_it );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** is_const ************** //
// ************************************************************************** //
template<typename C>
inline is_const<C>
is_const_coll( C& )
{
return is_const<C>();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** begin ************** //
// ************************************************************************** //
template<typename C>
inline static_any<BOOST_DEDUCED_TYPENAME C::iterator>
begin( C& t, mpl::false_ )
{
return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.begin() );
}
//____________________________________________________________________________//
template<typename C>
inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>
begin( C const& t, mpl::true_ )
{
return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.begin() );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** end ************** //
// ************************************************************************** //
template<typename C>
inline static_any<BOOST_DEDUCED_TYPENAME C::iterator>
end( C& t, mpl::false_ )
{
return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.end() );
}
//____________________________________________________________________________//
template<typename C>
inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>
end( C const& t, mpl::true_ )
{
return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.end() );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** done ************** //
// ************************************************************************** //
template<typename C>
inline bool
done( static_any_t cur, static_any_t end, C&, mpl::false_ )
{
return static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ) ==
static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( end );
}
//____________________________________________________________________________//
template<typename C>
inline bool
done( static_any_t cur, static_any_t end, C const&, mpl::true_ )
{
return static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ) ==
static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( end );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** next ************** //
// ************************************************************************** //
template<typename C>
inline void
next( static_any_t cur, C&, mpl::false_ )
{
++static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur );
}
//____________________________________________________________________________//
template<typename C>
inline void
next( static_any_t cur, C const&, mpl::true_ )
{
++static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** prev ************** //
// ************************************************************************** //
template<typename C>
inline void
prev( static_any_t cur, C&, mpl::false_ )
{
--static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur );
}
//____________________________________________________________________________//
template<typename C>
inline void
prev( static_any_t cur, C const&, mpl::true_ )
{
--static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** deref ************** //
// ************************************************************************** //
template<class RefType,typename C>
inline RefType
deref( static_any_t cur, C&, ::boost::type<RefType>, mpl::false_ )
{
return *static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur );
}
//____________________________________________________________________________//
template<class RefType,typename C>
inline RefType
deref( static_any_t cur, C const&, ::boost::type<RefType>, mpl::true_ )
{
return *static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** BOOST_TEST_FOREACH ************** //
// ************************************************************************** //
#define BOOST_TEST_FE_ANY ::boost::unit_test::for_each::static_any_t
#define BOOST_TEST_FE_IS_CONST( COL ) ::boost::unit_test::for_each::is_const_coll( COL )
#define BOOST_TEST_FE_BEG( COL ) \
::boost::unit_test::for_each::begin( \
COL, \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#define BOOST_TEST_FE_END( COL ) \
::boost::unit_test::for_each::end( \
COL, \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#define BOOST_TEST_FE_DONE( COL ) \
::boost::unit_test::for_each::done( \
BOOST_TEST_FE_CUR_VAR, \
BOOST_TEST_FE_END_VAR, \
COL, \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#define BOOST_TEST_FE_NEXT( COL ) \
::boost::unit_test::for_each::next( \
BOOST_TEST_FE_CUR_VAR, \
COL, \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#define BOOST_TEST_FE_PREV( COL ) \
::boost::unit_test::for_each::prev( \
BOOST_TEST_FE_CUR_VAR, \
COL, \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#define BOOST_FOREACH_NOOP(COL) \
((void)&(COL))
#define BOOST_TEST_FE_DEREF( COL, RefType ) \
::boost::unit_test::for_each::deref( \
BOOST_TEST_FE_CUR_VAR, \
COL, \
::boost::type<RefType >(), \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#if BOOST_WORKAROUND( BOOST_MSVC, == 1310 )
#define BOOST_TEST_LINE_NUM
#else
#define BOOST_TEST_LINE_NUM __LINE__
#endif
#define BOOST_TEST_FE_CUR_VAR BOOST_JOIN( _fe_cur_, BOOST_TEST_LINE_NUM )
#define BOOST_TEST_FE_END_VAR BOOST_JOIN( _fe_end_, BOOST_TEST_LINE_NUM )
#define BOOST_TEST_FE_CON_VAR BOOST_JOIN( _fe_con_, BOOST_TEST_LINE_NUM )
#define BOOST_TEST_FOREACH( RefType, var, COL ) \
if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \
if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_END( COL ) ) {} else \
for( bool BOOST_TEST_FE_CON_VAR = true; \
BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); \
BOOST_TEST_FE_CON_VAR ? BOOST_TEST_FE_NEXT( COL ) : BOOST_FOREACH_NOOP( COL )) \
\
if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \
for( RefType var = BOOST_TEST_FE_DEREF( COL, RefType ); \
!BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \
/**/
#define BOOST_TEST_REVERSE_FOREACH( RefType, var, COL ) \
if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_END( COL ) ) {} else \
if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \
for( bool BOOST_TEST_FE_CON_VAR = true; \
BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); ) \
\
if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \
if( (BOOST_TEST_FE_PREV( COL ), false) ) {} else \
for( RefType var = BOOST_TEST_FE_DEREF( COL, RefType ); \
!BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \
/**/
//____________________________________________________________________________//
} // namespace for_each
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_FOREACH_HPP

View File

@@ -0,0 +1,133 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! Defines the is_cstring type trait
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_IS_CSTRING_HPP
#define BOOST_TEST_UTILS_IS_CSTRING_HPP
// Boost
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp>
#include <string>
#if defined(BOOST_TEST_STRING_VIEW)
#include <string_view>
#endif
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** is_cstring ************** //
// ************************************************************************** //
namespace ut_detail {
template<typename T>
struct is_cstring_impl : public mpl::false_ {};
template<typename T>
struct is_cstring_impl<T const*> : public is_cstring_impl<T*> {};
template<typename T>
struct is_cstring_impl<T const* const> : public is_cstring_impl<T*> {};
template<>
struct is_cstring_impl<char*> : public mpl::true_ {};
template<>
struct is_cstring_impl<wchar_t*> : public mpl::true_ {};
template <typename T, bool is_cstring = is_cstring_impl<typename boost::decay<T>::type>::value >
struct deduce_cstring_transform_impl;
template <typename T, bool is_cstring >
struct deduce_cstring_transform_impl<T&, is_cstring> : public deduce_cstring_transform_impl<T, is_cstring>{};
template <typename T, bool is_cstring >
struct deduce_cstring_transform_impl<T const, is_cstring> : public deduce_cstring_transform_impl<T, is_cstring>{};
template <typename T>
struct deduce_cstring_transform_impl<T, true> {
typedef typename boost::add_const<
typename boost::remove_pointer<
typename boost::decay<T>::type
>::type
>::type U;
typedef boost::unit_test::basic_cstring<U> type;
};
template <typename T>
struct deduce_cstring_transform_impl< T, false > {
typedef typename
boost::remove_const<
typename boost::remove_reference<T>::type
>::type type;
};
template <typename T>
struct deduce_cstring_transform_impl< std::basic_string<T, std::char_traits<T> >, false > {
typedef boost::unit_test::basic_cstring<typename boost::add_const<T>::type> type;
};
#if defined(BOOST_TEST_STRING_VIEW)
template <typename T>
struct deduce_cstring_transform_impl< std::basic_string_view<T, std::char_traits<T> >, false > {
private:
using sv_t = std::basic_string_view<T, std::char_traits<T> > ;
public:
using type = stringview_cstring_helper<typename boost::add_const<T>::type, sv_t>;
};
#endif
} // namespace ut_detail
template<typename T>
struct is_cstring : public ut_detail::is_cstring_impl<typename decay<T>::type> {};
template<typename T, bool is_cstring = is_cstring<typename boost::decay<T>::type>::value >
struct is_cstring_comparable: public mpl::false_ {};
template<typename T>
struct is_cstring_comparable< T, true > : public mpl::true_ {};
template<typename T>
struct is_cstring_comparable< std::basic_string<T, std::char_traits<T> >, false > : public mpl::true_ {};
#if defined(BOOST_TEST_STRING_VIEW)
template<typename T>
struct is_cstring_comparable< std::basic_string_view<T, std::char_traits<T> >, false > : public mpl::true_ {};
#endif
template<typename T>
struct is_cstring_comparable< boost::unit_test::basic_cstring<T>, false > : public mpl::true_ {};
template <class T>
struct deduce_cstring_transform {
typedef typename
boost::remove_const<
typename boost::remove_reference<T>::type
>::type U;
typedef typename ut_detail::deduce_cstring_transform_impl<typename boost::decay<U>::type>::type type;
};
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_UTILS_IS_CSTRING_HPP

View File

@@ -0,0 +1,267 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! Defines the is_forward_iterable collection type trait
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP
#define BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP
#if defined(BOOST_NO_CXX11_DECLTYPE) || \
defined(BOOST_NO_CXX11_NULLPTR) || \
defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
// this feature works with VC2012 upd 5 while BOOST_NO_CXX11_TRAILING_RESULT_TYPES is defined
#if !defined(BOOST_MSVC) || BOOST_MSVC_FULL_VER < 170061232 /* VC2012 upd 5 */
#define BOOST_TEST_FWD_ITERABLE_CXX03
#endif
#endif
#if defined(BOOST_TEST_FWD_ITERABLE_CXX03)
// Boost
#include <boost/mpl/bool.hpp>
// STL
#include <list>
#include <vector>
#include <map>
#include <set>
#else
// Boost
#include <boost/static_assert.hpp>
#include <boost/utility/declval.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/test/utils/is_cstring.hpp>
// STL
#include <utility>
#include <type_traits>
#endif
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
template<typename T>
struct is_forward_iterable;
// ************************************************************************** //
// ************** is_forward_iterable ************** //
// ************************************************************************** //
#if defined(BOOST_TEST_FWD_ITERABLE_CXX03) && !defined(BOOST_TEST_DOXYGEN_DOC__)
template<typename T>
struct is_forward_iterable : public mpl::false_ {};
template<typename T>
struct is_forward_iterable<T const> : public is_forward_iterable<T> {};
template<typename T>
struct is_forward_iterable<T&> : public is_forward_iterable<T> {};
template<typename T, std::size_t N>
struct is_forward_iterable< T [N] > : public mpl::true_ {};
template<typename T, typename A>
struct is_forward_iterable< std::vector<T, A> > : public mpl::true_ {};
template<typename T, typename A>
struct is_forward_iterable< std::list<T, A> > : public mpl::true_ {};
template<typename K, typename V, typename C, typename A>
struct is_forward_iterable< std::map<K, V, C, A> > : public mpl::true_ {};
template<typename K, typename C, typename A>
struct is_forward_iterable< std::set<K, C, A> > : public mpl::true_ {};
// string is also forward iterable, even if sometimes we want to treat the
// assertions differently.
template<>
struct is_forward_iterable< std::string > : public mpl::true_ {};
#else
namespace ut_detail {
// SFINAE helper
template<typename T>
struct is_present : public mpl::true_ {};
//____________________________________________________________________________//
// some compiler do not implement properly decltype non expression involving members (eg. VS2013)
// a workaround is to use -> decltype syntax.
template <class T>
struct has_member_size {
private:
struct nil_t {};
template<typename U> static auto test( U* ) -> decltype(boost::declval<U>().size());
template<typename> static nil_t test( ... );
public:
static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
};
//____________________________________________________________________________//
template <class T>
struct has_member_begin {
private:
struct nil_t {};
template<typename U> static auto test( U* ) -> decltype(std::begin(boost::declval<U&>())); // does not work with boost::begin
template<typename> static nil_t test( ... );
public:
static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
};
//____________________________________________________________________________//
template <class T>
struct has_member_end {
private:
struct nil_t {};
template<typename U> static auto test( U* ) -> decltype(std::end(boost::declval<U&>())); // does not work with boost::end
template<typename> static nil_t test( ... );
public:
static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
};
//____________________________________________________________________________//
template <class T, class enabled = void>
struct is_forward_iterable_impl : std::false_type {
};
template <class T>
struct is_forward_iterable_impl<
T,
typename std::enable_if<
has_member_begin<T>::value &&
has_member_end<T>::value
>::type
> : std::true_type
{};
//____________________________________________________________________________//
template <class T, class enabled = void>
struct is_container_forward_iterable_impl : std::false_type {
};
template <class T>
struct is_container_forward_iterable_impl<
T,
typename std::enable_if<
is_present<typename T::const_iterator>::value &&
is_present<typename T::value_type>::value &&
has_member_size<T>::value &&
is_forward_iterable_impl<T>::value
>::type
> : is_forward_iterable_impl<T>
{};
//____________________________________________________________________________//
} // namespace ut_detail
/*! Indicates that a specific type implements the forward iterable concept. */
template<typename T>
struct is_forward_iterable {
typedef typename std::remove_reference<T>::type T_ref;
typedef ut_detail::is_forward_iterable_impl<T_ref> is_fwd_it_t;
typedef mpl::bool_<is_fwd_it_t::value> type;
enum { value = is_fwd_it_t::value };
};
/*! Indicates that a specific type implements the forward iterable concept. */
template<typename T>
struct is_container_forward_iterable {
typedef typename std::remove_reference<T>::type T_ref;
typedef ut_detail::is_container_forward_iterable_impl<T_ref> is_fwd_it_t;
typedef mpl::bool_<is_fwd_it_t::value> type;
enum { value = is_fwd_it_t::value };
};
#endif /* defined(BOOST_TEST_FWD_ITERABLE_CXX03) */
//! Helper structure for accessing the content of a container or an array
template <typename T, bool is_forward_iterable = is_forward_iterable<T>::value >
struct bt_iterator_traits;
template <typename T>
struct bt_iterator_traits< T, true >{
BOOST_STATIC_ASSERT((is_forward_iterable<T>::value));
#if defined(BOOST_TEST_FWD_ITERABLE_CXX03) || \
(defined(BOOST_MSVC) && (BOOST_MSVC_FULL_VER <= 170061232))
typedef typename T::const_iterator const_iterator;
typedef typename std::iterator_traits<const_iterator>::value_type value_type;
#else
typedef decltype(boost::declval<
typename boost::add_const<
typename boost::remove_reference<T>::type
>::type>().begin()) const_iterator;
typedef typename std::iterator_traits<const_iterator>::value_type value_type;
#endif /* BOOST_TEST_FWD_ITERABLE_CXX03 */
static const_iterator begin(T const& container) {
return container.begin();
}
static const_iterator end(T const& container) {
return container.end();
}
#if defined(BOOST_TEST_FWD_ITERABLE_CXX03) || \
(defined(BOOST_MSVC) && (BOOST_MSVC_FULL_VER <= 170061232))
static std::size_t
size(T const& container) {
return container.size();
}
#else
static std::size_t
size(T const& container) {
return size(container,
std::integral_constant<bool, ut_detail::has_member_size<T>::value>());
}
private:
static std::size_t
size(T const& container, std::true_type) { return container.size(); }
static std::size_t
size(T const& container, std::false_type) { return std::distance(begin(container), end(container)); }
#endif /* BOOST_TEST_FWD_ITERABLE_CXX03 */
};
template <typename T, std::size_t N>
struct bt_iterator_traits< T [N], true > {
typedef typename boost::add_const<T>::type T_const;
typedef typename boost::add_pointer<T_const>::type const_iterator;
typedef T value_type;
static const_iterator begin(T_const (&array)[N]) {
return &array[0];
}
static const_iterator end(T_const (&array)[N]) {
return &array[N];
}
static std::size_t size(T_const (&)[N]) {
return N;
}
};
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP

View File

@@ -0,0 +1,105 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//! Input iterator facade
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_INPUT_ITERATOR_FACADE_HPP
#define BOOST_TEST_UTILS_INPUT_ITERATOR_FACADE_HPP
// Boost
#include <boost/iterator/iterator_facade.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace utils {
// ************************************************************************** //
// ************** input_iterator_core_access ************** //
// ************************************************************************** //
class input_iterator_core_access
{
#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
public:
#else
template <class I, class V, class R, class TC> friend class input_iterator_facade;
#endif
template <class Facade>
static bool get( Facade& f )
{
return f.get();
}
private:
// objects of this class are useless
input_iterator_core_access(); //undefined
};
// ************************************************************************** //
// ************** input_iterator_facade ************** //
// ************************************************************************** //
template<typename Derived,
typename ValueType,
typename Reference = ValueType const&,
typename Traversal = single_pass_traversal_tag>
class input_iterator_facade : public iterator_facade<Derived,ValueType,Traversal,Reference>
{
public:
// Constructor
input_iterator_facade() : m_valid( false ), m_value() {}
protected: // provide access to the Derived
void init()
{
m_valid = true;
increment();
}
// Data members
mutable bool m_valid;
ValueType m_value;
private:
friend class boost::iterator_core_access;
// iterator facade interface implementation
void increment()
{
// we make post-end incrementation indefinetly safe
if( m_valid )
m_valid = input_iterator_core_access::get( *static_cast<Derived*>(this) );
}
Reference dereference() const
{
return m_value;
}
// iterator facade interface implementation
bool equal( input_iterator_facade const& rhs ) const
{
// two invalid iterator equals, inequal otherwise
return !m_valid && !rhs.m_valid;
}
};
} // namespace utils
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_INPUT_ITERATOR_FACADE_HPP

View File

@@ -0,0 +1,421 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : token iterator for string and range tokenization
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_TOKEN_ITERATOR_HPP
#define BOOST_TEST_UTILS_TOKEN_ITERATOR_HPP
// Boost
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/test/utils/iterator/input_iterator_facade.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/named_params.hpp>
#include <boost/test/utils/foreach.hpp>
// STL
#include <iosfwd>
#include <cctype>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ using ::ispunct; using ::isspace; }
#endif
namespace boost {
namespace unit_test {
namespace utils {
// ************************************************************************** //
// ************** ti_delimeter_type ************** //
// ************************************************************************** //
enum ti_delimeter_type {
dt_char, // character is delimeter if it among explicit list of some characters
dt_ispunct, // character is delimeter if it satisfies ispunct functor
dt_isspace, // character is delimeter if it satisfies isspace functor
dt_none // no character is delimeter
};
namespace ut_detail {
// ************************************************************************** //
// ************** default_char_compare ************** //
// ************************************************************************** //
template<typename CharT>
class default_char_compare {
public:
bool operator()( CharT c1, CharT c2 )
{
#ifdef BOOST_CLASSIC_IOSTREAMS
return std::string_char_traits<CharT>::eq( c1, c2 );
#else
return std::char_traits<CharT>::eq( c1, c2 );
#endif
}
};
// ************************************************************************** //
// ************** delim_policy ************** //
// ************************************************************************** //
template<typename CharT,typename CharCompare>
class delim_policy {
typedef basic_cstring<CharT const> cstring;
public:
// Constructor
explicit delim_policy( ti_delimeter_type type_ = dt_char, cstring delimeters_ = cstring() )
: m_type( type_ )
{
set_delimeters( delimeters_ );
}
void set_delimeters( ti_delimeter_type type_ ) { m_type = type_; }
void set_delimeters( cstring delimeters_ )
{
m_delimeters = delimeters_;
if( !m_delimeters.is_empty() )
m_type = dt_char;
}
void set_delimeters( nfp::nil ) {}
bool operator()( CharT c )
{
switch( m_type ) {
case dt_char: {
BOOST_TEST_FOREACH( CharT, delim, m_delimeters )
if( CharCompare()( delim, c ) )
return true;
return false;
}
case dt_ispunct:
return (std::ispunct)( c ) != 0;
case dt_isspace:
return (std::isspace)( c ) != 0;
case dt_none:
return false;
}
return false;
}
private:
// Data members
cstring m_delimeters;
ti_delimeter_type m_type;
};
// ************************************************************************** //
// ************** token_assigner ************** //
// ************************************************************************** //
template<typename TraversalTag>
struct token_assigner {
#if BOOST_WORKAROUND( BOOST_DINKUMWARE_STDLIB, < 306 )
template<typename Iterator, typename C, typename T>
static void assign( Iterator b, Iterator e, std::basic_string<C,T>& t )
{ for( ; b != e; ++b ) t += *b; }
template<typename Iterator, typename C>
static void assign( Iterator b, Iterator e, basic_cstring<C>& t ) { t.assign( b, e ); }
#else
template<typename Iterator, typename Token>
static void assign( Iterator b, Iterator e, Token& t ) { t.assign( b, e ); }
#endif
template<typename Iterator, typename Token>
static void append_move( Iterator& b, Token& ) { ++b; }
};
//____________________________________________________________________________//
template<>
struct token_assigner<single_pass_traversal_tag> {
template<typename Iterator, typename Token>
static void assign( Iterator /*b*/, Iterator /*e*/, Token& /*t*/ ) {}
template<typename Iterator, typename Token>
static void append_move( Iterator& b, Token& t ) { t += *b; ++b; }
};
} // namespace ut_detail
// ************************************************************************** //
// ************** modifiers ************** //
// ************************************************************************** //
namespace {
nfp::keyword<struct dropped_delimeters_t > dropped_delimeters;
nfp::keyword<struct kept_delimeters_t > kept_delimeters;
nfp::typed_keyword<bool,struct keep_empty_tokens_t > keep_empty_tokens;
nfp::typed_keyword<std::size_t,struct max_tokens_t > max_tokens;
}
// ************************************************************************** //
// ************** token_iterator_base ************** //
// ************************************************************************** //
template<typename Derived,
typename CharT,
typename CharCompare = ut_detail::default_char_compare<CharT>,
typename ValueType = basic_cstring<CharT const>,
typename Reference = basic_cstring<CharT const>,
typename Traversal = forward_traversal_tag>
class token_iterator_base
: public input_iterator_facade<Derived,ValueType,Reference,Traversal> {
typedef basic_cstring<CharT const> cstring;
typedef ut_detail::delim_policy<CharT,CharCompare> delim_policy;
typedef input_iterator_facade<Derived,ValueType,Reference,Traversal> base;
protected:
// Constructor
explicit token_iterator_base()
: m_is_dropped( dt_isspace )
, m_is_kept( dt_ispunct )
, m_keep_empty_tokens( false )
, m_tokens_left( static_cast<std::size_t>(-1) )
, m_token_produced( false )
{
}
template<typename Modifier>
void
apply_modifier( Modifier const& m )
{
if( m.has( dropped_delimeters ) )
m_is_dropped.set_delimeters( m[dropped_delimeters] );
if( m.has( kept_delimeters ) )
m_is_kept.set_delimeters( m[kept_delimeters] );
if( m.has( keep_empty_tokens ) )
m_keep_empty_tokens = true;
nfp::opt_assign( m_tokens_left, m, max_tokens );
}
template<typename Iter>
bool get( Iter& begin, Iter end )
{
typedef ut_detail::token_assigner<BOOST_DEDUCED_TYPENAME iterator_traversal<Iter>::type> Assigner;
Iter check_point;
this->m_value.clear();
if( !m_keep_empty_tokens ) {
while( begin != end && m_is_dropped( *begin ) )
++begin;
if( begin == end )
return false;
check_point = begin;
if( m_tokens_left == 1 )
while( begin != end )
Assigner::append_move( begin, this->m_value );
else if( m_is_kept( *begin ) )
Assigner::append_move( begin, this->m_value );
else
while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
Assigner::append_move( begin, this->m_value );
--m_tokens_left;
}
else { // m_keep_empty_tokens is true
check_point = begin;
if( begin == end ) {
if( m_token_produced )
return false;
m_token_produced = true;
}
if( m_is_kept( *begin ) ) {
if( m_token_produced )
Assigner::append_move( begin, this->m_value );
m_token_produced = !m_token_produced;
}
else if( !m_token_produced && m_is_dropped( *begin ) )
m_token_produced = true;
else {
if( m_is_dropped( *begin ) )
check_point = ++begin;
while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
Assigner::append_move( begin, this->m_value );
m_token_produced = true;
}
}
Assigner::assign( check_point, begin, this->m_value );
return true;
}
private:
// Data members
delim_policy m_is_dropped;
delim_policy m_is_kept;
bool m_keep_empty_tokens;
std::size_t m_tokens_left;
bool m_token_produced;
};
// ************************************************************************** //
// ************** basic_string_token_iterator ************** //
// ************************************************************************** //
template<typename CharT,
typename CharCompare = ut_detail::default_char_compare<CharT> >
class basic_string_token_iterator
: public token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> {
typedef basic_cstring<CharT const> cstring;
typedef token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> base;
public:
explicit basic_string_token_iterator() {}
explicit basic_string_token_iterator( cstring src )
: m_src( src )
{
this->init();
}
// warning: making the constructor accept anything else than a cstring should
// ensure that no temporary object is created during string creation (previous
// definition was "template<typename Src, typename Modifier> basic_string_token_iterator( Src src ..."
// which may create a temporary string copy when called with an std::string.
template<typename Modifier>
basic_string_token_iterator( cstring src, Modifier const& m )
: m_src( src )
{
this->apply_modifier( m );
this->init();
}
private:
friend class input_iterator_core_access;
// input iterator implementation
bool get()
{
typename cstring::iterator begin = m_src.begin();
bool res = base::get( begin, m_src.end() );
m_src.assign( begin, m_src.end() );
return res;
}
// Data members
cstring m_src;
};
typedef basic_string_token_iterator<char> string_token_iterator;
typedef basic_string_token_iterator<wchar_t> wstring_token_iterator;
// ************************************************************************** //
// ************** range_token_iterator ************** //
// ************************************************************************** //
template<typename Iter,
typename CharCompare = ut_detail::default_char_compare<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
typename ValueType = std::basic_string<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
typename Reference = ValueType const&>
class range_token_iterator
: public token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> {
typedef basic_cstring<typename ValueType::value_type> cstring;
typedef token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> base;
public:
explicit range_token_iterator() {}
explicit range_token_iterator( Iter begin, Iter end = Iter() )
: m_begin( begin ), m_end( end )
{
this->init();
}
range_token_iterator( range_token_iterator const& rhs )
: base( rhs )
{
if( this->m_valid ) {
m_begin = rhs.m_begin;
m_end = rhs.m_end;
}
}
template<typename Modifier>
range_token_iterator( Iter begin, Iter end, Modifier const& m )
: m_begin( begin ), m_end( end )
{
this->apply_modifier( m );
this->init();
}
private:
friend class input_iterator_core_access;
// input iterator implementation
bool get()
{
return base::get( m_begin, m_end );
}
// Data members
Iter m_begin;
Iter m_end;
};
// ************************************************************************** //
// ************** make_range_token_iterator ************** //
// ************************************************************************** //
template<typename Iter>
inline range_token_iterator<Iter>
make_range_token_iterator( Iter begin, Iter end = Iter() )
{
return range_token_iterator<Iter>( begin, end );
}
//____________________________________________________________________________//
template<typename Iter,typename Modifier>
inline range_token_iterator<Iter>
make_range_token_iterator( Iter begin, Iter end, Modifier const& m )
{
return range_token_iterator<Iter>( begin, end, m );
}
//____________________________________________________________________________//
} // namespace utils
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_TOKEN_ITERATOR_HPP

View File

@@ -0,0 +1,144 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// Description : contains definition for all test tools in test toolbox
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_LAZY_OSTREAM_HPP
#define BOOST_TEST_UTILS_LAZY_OSTREAM_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/tools/detail/print_helper.hpp>
// STL
#include <iosfwd>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** lazy_ostream ************** //
// ************************************************************************** //
namespace boost {
namespace unit_test {
class BOOST_TEST_DECL lazy_ostream {
public:
virtual ~lazy_ostream() {}
static lazy_ostream& instance() { return inst; }
#if !defined(BOOST_EMBTC)
friend std::ostream& operator<<( std::ostream& ostr, lazy_ostream const& o ) { return o( ostr ); }
#else
friend std::ostream& operator<<( std::ostream& ostr, lazy_ostream const& o );
#endif
// access method
bool empty() const { return m_empty; }
// actual printing interface; to be accessed only by this class and children
virtual std::ostream& operator()( std::ostream& ostr ) const { return ostr; }
protected:
explicit lazy_ostream( bool p_empty = true ) : m_empty( p_empty ) {}
private:
// Data members
bool m_empty;
static lazy_ostream inst;
};
#if defined(BOOST_EMBTC)
inline std::ostream& operator<<( std::ostream& ostr, lazy_ostream const& o ) { return o( ostr ); }
#endif
//____________________________________________________________________________//
template<typename PrevType, typename T, typename StorageT=T const&>
class lazy_ostream_impl : public lazy_ostream {
public:
lazy_ostream_impl( PrevType const& prev, T const& value )
: lazy_ostream( false )
, m_prev( prev )
, m_value( value )
{
}
std::ostream& operator()( std::ostream& ostr ) const BOOST_OVERRIDE
{
return m_prev(ostr) << test_tools::tt_detail::print_helper(m_value);
}
private:
// Data members
PrevType const& m_prev;
StorageT m_value;
};
//____________________________________________________________________________//
template<typename T>
inline lazy_ostream_impl<lazy_ostream,T>
operator<<( lazy_ostream const& prev, T const& v )
{
return lazy_ostream_impl<lazy_ostream,T>( prev, v );
}
//____________________________________________________________________________//
template<typename PrevPrevType, typename TPrev, typename T>
inline lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,T>
operator<<( lazy_ostream_impl<PrevPrevType,TPrev> const& prev, T const& v )
{
typedef lazy_ostream_impl<PrevPrevType,TPrev> PrevType;
return lazy_ostream_impl<PrevType,T>( prev, v );
}
//____________________________________________________________________________//
#if BOOST_TEST_USE_STD_LOCALE
template<typename R,typename S>
inline lazy_ostream_impl<lazy_ostream,R& (BOOST_TEST_CALL_DECL *)(S&),R& (BOOST_TEST_CALL_DECL *)(S&)>
operator<<( lazy_ostream const& prev, R& (BOOST_TEST_CALL_DECL *man)(S&) )
{
typedef R& (BOOST_TEST_CALL_DECL * ManipType)(S&);
return lazy_ostream_impl<lazy_ostream,ManipType,ManipType>( prev, man );
}
//____________________________________________________________________________//
template<typename PrevPrevType, typename TPrev,typename R,typename S>
inline lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,R& (BOOST_TEST_CALL_DECL *)(S&),R& (BOOST_TEST_CALL_DECL *)(S&)>
operator<<( lazy_ostream_impl<PrevPrevType,TPrev> const& prev, R& (BOOST_TEST_CALL_DECL *man)(S&) )
{
typedef R& (BOOST_TEST_CALL_DECL * ManipType)(S&);
return lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,ManipType,ManipType>( prev, man );
}
//____________________________________________________________________________//
#endif
#define BOOST_TEST_LAZY_MSG( M ) (::boost::unit_test::lazy_ostream::instance() << M)
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_LAZY_OSTREAM_HPP

View File

@@ -0,0 +1,388 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : named function parameters library
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_NAMED_PARAM
#define BOOST_TEST_UTILS_NAMED_PARAM
// Boost
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
// Boost.Test
#include <boost/test/utils/rtti.hpp>
#include <boost/test/utils/assign_op.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/test/detail/throw_exception.hpp>
// Boost
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace nfp { // named function parameters
// ************************************************************************** //
// ************** forward declarations ************** //
// ************************************************************************** //
template<typename unique_id, bool required> struct keyword;
template<typename T, typename unique_id, bool required = false> struct typed_keyword;
template<typename T, typename unique_id, typename RefType=T&> struct named_parameter;
template<typename NP1,typename NP2> struct named_parameter_combine;
// ************************************************************************** //
// ************** is_named_param_pack ************** //
// ************************************************************************** //
/// is_named_param_pack<T>::value is true if T is parameters pack
template<typename T>
struct is_named_param_pack : public mpl::false_ {};
template<typename T, typename unique_id, typename RefType>
struct is_named_param_pack<named_parameter<T,unique_id,RefType> > : public mpl::true_ {};
template<typename NP, typename Rest>
struct is_named_param_pack<named_parameter_combine<NP,Rest> > : public mpl::true_ {};
// ************************************************************************** //
// ************** param_type ************** //
// ************************************************************************** //
/// param_type<Params,Keyword,Default>::type is the type of the parameter
/// corresponding to the Keyword (if parameter is present) or Default
template<typename NP, typename Keyword, typename DefaultType=void>
struct param_type
: mpl::if_<typename is_same<typename NP::id,typename Keyword::id>::type,
typename remove_cv<typename NP::data_type>::type,
DefaultType> {};
template<typename NP, typename Rest, typename Keyword, typename DefaultType>
struct param_type<named_parameter_combine<NP,Rest>,Keyword,DefaultType>
: mpl::if_<typename is_same<typename NP::id,typename Keyword::id>::type,
typename remove_cv<typename NP::data_type>::type,
typename param_type<Rest,Keyword,DefaultType>::type> {};
// ************************************************************************** //
// ************** has_param ************** //
// ************************************************************************** //
/// has_param<Params,Keyword>::value is true if Params has parameter corresponding
/// to the Keyword
template<typename NP, typename Keyword>
struct has_param : is_same<typename NP::id,typename Keyword::id> {};
template<typename NP, typename Rest, typename Keyword>
struct has_param<named_parameter_combine<NP,Rest>,Keyword>
: mpl::or_<typename is_same<typename NP::id,typename Keyword::id>::type,
typename has_param<Rest,Keyword>::type> {};
// ************************************************************************** //
// ************** access_to_invalid_parameter ************** //
// ************************************************************************** //
namespace nfp_detail {
struct access_to_invalid_parameter {};
//____________________________________________________________________________//
inline void
report_access_to_invalid_parameter( bool v )
{
BOOST_TEST_I_ASSRT( !v, access_to_invalid_parameter() );
}
} // namespace nfp_detail
// ************************************************************************** //
// ************** nil ************** //
// ************************************************************************** //
struct nil {
template<typename T>
#if defined(__GNUC__) || defined(__HP_aCC) || defined(__EDG__) || defined(__SUNPRO_CC) || defined(BOOST_EMBTC)
operator T() const
#else
operator T const&() const
#endif
{ nfp_detail::report_access_to_invalid_parameter(true); static T* v = 0; return *v; }
template<typename T>
T any_cast() const
{ nfp_detail::report_access_to_invalid_parameter(true); static typename remove_reference<T>::type* v = 0; return *v; }
template<typename Arg1>
nil operator()( Arg1 const& )
{ nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
template<typename Arg1,typename Arg2>
nil operator()( Arg1 const&, Arg2 const& )
{ nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
template<typename Arg1,typename Arg2,typename Arg3>
nil operator()( Arg1 const&, Arg2 const&, Arg3 const& )
{ nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
// Visitation support
template<typename Visitor>
void apply_to( Visitor& /*v*/ ) const {}
static nil& inst() { static nil s_inst; return s_inst; }
private:
nil() {}
};
// ************************************************************************** //
// ************** named_parameter_base ************** //
// ************************************************************************** //
namespace nfp_detail {
template<typename Derived>
struct named_parameter_base {
template<typename NP>
named_parameter_combine<NP,Derived>
operator,( NP const& np ) const { return named_parameter_combine<NP,Derived>( np, *static_cast<Derived const*>(this) ); }
};
} // namespace nfp_detail
// ************************************************************************** //
// ************** named_parameter_combine ************** //
// ************************************************************************** //
template<typename NP, typename Rest = nil>
struct named_parameter_combine
: Rest
, nfp_detail::named_parameter_base<named_parameter_combine<NP,Rest> > {
typedef typename NP::ref_type res_type;
typedef named_parameter_combine<NP,Rest> self_type;
// Constructor
named_parameter_combine( NP const& np, Rest const& r )
: Rest( r )
, m_param( np )
{
}
// Access methods
res_type operator[]( keyword<typename NP::id,true> kw ) const { return m_param[kw]; }
res_type operator[]( keyword<typename NP::id,false> kw ) const { return m_param[kw]; }
using Rest::operator[];
bool has( keyword<typename NP::id,false> kw ) const { return m_param.has( kw ); }
using Rest::has;
void erase( keyword<typename NP::id,false> kw ) const { m_param.erase( kw ); }
using Rest::erase;
using nfp_detail::named_parameter_base<named_parameter_combine<NP,Rest> >::operator,;
// Visitation support
template<typename Visitor>
void apply_to( Visitor& V ) const
{
m_param.apply_to( V );
Rest::apply_to( V );
}
private:
// Data members
NP m_param;
};
// ************************************************************************** //
// ************** named_parameter ************** //
// ************************************************************************** //
template<typename T, typename unique_id, typename RefType>
struct named_parameter
: nfp_detail::named_parameter_base<named_parameter<T,unique_id,RefType> >
{
typedef T data_type;
typedef RefType ref_type;
typedef unique_id id;
// Constructor
explicit named_parameter( ref_type v )
: m_value( v )
, m_erased( false )
{}
named_parameter( named_parameter const& np )
: m_value( np.m_value )
, m_erased( np.m_erased )
{}
// Access methods
ref_type operator[]( keyword<unique_id,true> ) const { return m_erased ? nil::inst().template any_cast<ref_type>() : m_value; }
ref_type operator[]( keyword<unique_id,false> ) const { return m_erased ? nil::inst().template any_cast<ref_type>() : m_value; }
template<typename UnknownId>
nil operator[]( keyword<UnknownId,false> ) const { return nil::inst(); }
bool has( keyword<unique_id,false> ) const { return !m_erased; }
template<typename UnknownId>
bool has( keyword<UnknownId,false> ) const { return false; }
void erase( keyword<unique_id,false> ) const { m_erased = true; }
template<typename UnknownId>
void erase( keyword<UnknownId,false> ) const {}
// Visitation support
template<typename Visitor>
void apply_to( Visitor& V ) const
{
V.set_parameter( rtti::type_id<unique_id>(), m_value );
}
private:
// Data members
ref_type m_value;
mutable bool m_erased;
};
// ************************************************************************** //
// ************** no_params ************** //
// ************************************************************************** //
typedef named_parameter<char, struct no_params_type_t,char> no_params_type;
namespace {
no_params_type no_params( '\0' );
} // local namespace
// ************************************************************************** //
// ************** keyword ************** //
// ************************************************************************** //
template<typename unique_id, bool required = false>
struct keyword {
typedef unique_id id;
template<typename T>
named_parameter<T const,unique_id>
operator=( T const& t ) const { return named_parameter<T const,unique_id>( t ); }
template<typename T>
named_parameter<T,unique_id>
operator=( T& t ) const { return named_parameter<T,unique_id>( t ); }
named_parameter<char const*,unique_id,char const*>
operator=( char const* t ) const { return named_parameter<char const*,unique_id,char const*>( t ); }
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** typed_keyword ************** //
// ************************************************************************** //
template<typename T, typename unique_id, bool required>
struct typed_keyword : keyword<unique_id,required> {
named_parameter<T const,unique_id>
operator=( T const& t ) const { return named_parameter<T const,unique_id>( t ); }
named_parameter<T,unique_id>
operator=( T& t ) const { return named_parameter<T,unique_id>( t ); }
};
//____________________________________________________________________________//
template<typename unique_id, bool required>
struct typed_keyword<bool,unique_id,required>
: keyword<unique_id,required>
, named_parameter<bool,unique_id,bool> {
typedef unique_id id;
typed_keyword() : named_parameter<bool,unique_id,bool>( true ) {}
named_parameter<bool,unique_id,bool>
operator!() const { return named_parameter<bool,unique_id,bool>( false ); }
};
// ************************************************************************** //
// ************** opt_assign ************** //
// ************************************************************************** //
template<typename T, typename Params, typename Keyword>
inline typename enable_if_c<!has_param<Params,Keyword>::value,void>::type
opt_assign( T& /*target*/, Params const& /*p*/, Keyword /*k*/ )
{
}
//____________________________________________________________________________//
template<typename T, typename Params, typename Keyword>
inline typename enable_if_c<has_param<Params,Keyword>::value,void>::type
opt_assign( T& target, Params const& p, Keyword k )
{
using namespace unit_test;
assign_op( target, p[k], static_cast<int>(0) );
}
// ************************************************************************** //
// ************** opt_get ************** //
// ************************************************************************** //
template<typename T, typename Params, typename Keyword>
inline T
opt_get( Params const& p, Keyword k, T default_val )
{
opt_assign( default_val, p, k );
return default_val;
}
// ************************************************************************** //
// ************** opt_get ************** //
// ************************************************************************** //
template<typename Params, typename NP>
inline typename enable_if_c<!has_param<Params,keyword<typename NP::id> >::value,
named_parameter_combine<NP,Params> >::type
opt_append( Params const& params, NP const& np )
{
return (params,np);
}
//____________________________________________________________________________//
template<typename Params, typename NP>
inline typename enable_if_c<has_param<Params,keyword<typename NP::id> >::value,Params>::type
opt_append( Params const& params, NP const& )
{
return params;
}
} // namespace nfp
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_NAMED_PARAM

View File

@@ -0,0 +1,103 @@
// (C) Copyright Gennadiy Rozental 2001.
// (C) Copyright Daryle Walker 2000-2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : simulate /dev/null stream
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_NULLSTREAM_HPP
#define BOOST_TEST_UTILS_NULLSTREAM_HPP
// STL
#include <ostream> // for std::basic_ostream
#include <streambuf> // for std::basic_streambuf
#include <string> // for std::char_traits
// Boost
#include <boost/utility/base_from_member.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
// ************************************************************************** //
// ************** basic_nullbuf ************** //
// ************************************************************************** //
// Class for a buffer that reads nothing and writes to nothing.
// Idea from an Usenet post by Tom <the_wid@my-deja.com> at
// 27 Oct 2000 14:06:21 GMT on comp.lang.c++.
template<typename CharType, class CharTraits = ::std::char_traits<CharType> >
class basic_nullbuf : public ::std::basic_streambuf<CharType, CharTraits> {
typedef ::std::basic_streambuf<CharType, CharTraits> base_type;
public:
// Types
typedef typename base_type::char_type char_type;
typedef typename base_type::traits_type traits_type;
typedef typename base_type::int_type int_type;
typedef typename base_type::pos_type pos_type;
typedef typename base_type::off_type off_type;
// Use automatic default constructor and destructor
protected:
// The default implementations of the miscellaneous virtual
// member functions are sufficient.
// The default implementations of the input & putback virtual
// member functions, being nowhere but EOF, are sufficient.
// The output virtual member functions need to be changed to
// accept anything without any problems, instead of being at EOF.
virtual ::std::streamsize xsputn( char_type const* /*s*/, ::std::streamsize n ) { return n; } // "s" is unused
virtual int_type overflow( int_type c = traits_type::eof() ) { return traits_type::not_eof( c ); }
};
typedef basic_nullbuf<char> nullbuf;
typedef basic_nullbuf<wchar_t> wnullbuf;
// ************************************************************************** //
// ************** basic_onullstream ************** //
// ************************************************************************** //
// Output streams based on basic_nullbuf.
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
template< typename CharType, class CharTraits = ::std::char_traits<CharType> >
class basic_onullstream : private boost::base_from_member<basic_nullbuf<CharType, CharTraits> >
, public ::std::basic_ostream<CharType, CharTraits> {
typedef boost::base_from_member<basic_nullbuf<CharType, CharTraits> > pbase_type;
typedef ::std::basic_ostream<CharType, CharTraits> base_type;
public:
// Constructor
basic_onullstream() : pbase_type(), base_type( &this->pbase_type::member ) {}
};
#ifdef BOOST_MSVC
# pragma warning(default: 4355)
# pragma warning(pop)
#endif
typedef basic_onullstream<char> onullstream;
typedef basic_onullstream<wchar_t> wonullstream;
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_NULLSTREAM_HPP

View File

@@ -0,0 +1,64 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : simple facilities for accessing type information at runtime
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RTTI_HPP
#define BOOST_TEST_UTILS_RTTI_HPP
// C Runtime
#include <cstddef>
#include <boost/test/detail/config.hpp>
namespace boost {
namespace rtti {
// ************************************************************************** //
// ************** rtti::type_id ************** //
// ************************************************************************** //
typedef std::ptrdiff_t id_t;
namespace rtti_detail {
template<typename T>
struct BOOST_TEST_DECL rttid_holder {
static id_t id() { return reinterpret_cast<id_t>( &inst() ); }
private:
struct rttid {};
static rttid const& inst() { static rttid s_inst; return s_inst; }
};
} // namespace rtti_detail
//____________________________________________________________________________//
template<typename T>
BOOST_TEST_DECL inline id_t
type_id()
{
return rtti_detail::rttid_holder<T>::id();
}
//____________________________________________________________________________//
#define BOOST_RTTI_SWITCH( type_id_ ) if( ::boost::rtti::id_t switch_by_id = type_id_ )
#define BOOST_RTTI_CASE( type ) if( switch_by_id == ::boost::rtti::type_id<type>() )
//____________________________________________________________________________//
} // namespace rtti
} // namespace boost
#endif // BOOST_TEST_UTILS_RTTI_HPP

View File

@@ -0,0 +1,131 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : model of actual argument (both typed and abstract interface)
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
#define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/utils/runtime/errors.hpp>
// Boost.Test
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/rtti.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/test/detail/throw_exception.hpp>
// STL
#include <cassert>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
// ************************************************************************** //
// ************** runtime::argument ************** //
// ************************************************************************** //
class argument {
public:
// Constructor
argument( rtti::id_t value_type )
: p_value_type( value_type )
{}
// Destructor
virtual ~argument() {}
// Public properties
rtti::id_t const p_value_type;
};
// ************************************************************************** //
// ************** runtime::typed_argument ************** //
// ************************************************************************** //
template<typename T>
class typed_argument : public argument {
public:
// Constructor
explicit typed_argument( T const& v )
: argument( rtti::type_id<T>() )
, p_value( v )
{}
unit_test::readwrite_property<T> p_value;
};
// ************************************************************************** //
// ************** runtime::arguments_store ************** //
// ************************************************************************** //
class arguments_store {
public:
typedef std::map<cstring, argument_ptr> storage_type;
/// Returns number of arguments in the store; mostly used for testing
std::size_t size() const { return m_arguments.size(); }
/// Clears the store for reuse
void clear() { m_arguments.clear(); }
/// Returns true if there is an argument corresponding to the specified parameter name
bool has( cstring parameter_name ) const
{
return m_arguments.find( parameter_name ) != m_arguments.end();
}
/// Provides types access to argument value by parameter name
template<typename T>
T const& get( cstring parameter_name ) const {
return const_cast<arguments_store*>(this)->get<T>( parameter_name );
}
template<typename T>
T& get( cstring parameter_name ) {
storage_type::const_iterator found = m_arguments.find( parameter_name );
BOOST_TEST_I_ASSRT( found != m_arguments.end(),
access_to_missing_argument()
<< "There is no argument provided for parameter "
<< parameter_name );
argument_ptr arg = found->second;
BOOST_TEST_I_ASSRT( arg->p_value_type == rtti::type_id<T>(),
arg_type_mismatch()
<< "Access with invalid type for argument corresponding to parameter "
<< parameter_name );
return static_cast<typed_argument<T>&>( *arg ).p_value.value;
}
/// Set's the argument value for specified parameter name
template<typename T>
void set( cstring parameter_name, T const& value )
{
m_arguments[parameter_name] = argument_ptr( new typed_argument<T>( value ) );
}
private:
// Data members
storage_type m_arguments;
};
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP

View File

@@ -0,0 +1,243 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : argument factories for different kinds of parameters
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP
#define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/errors.hpp>
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/utils/runtime/modifier.hpp>
// Boost.Test
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/test/utils/string_cast.hpp>
// Boost
#include <boost/function/function2.hpp>
// STL
#include <vector>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
// ************************************************************************** //
// ************** runtime::value_interpreter ************** //
// ************************************************************************** //
template<typename ValueType, bool is_enum>
struct value_interpreter;
//____________________________________________________________________________//
template<typename ValueType>
struct value_interpreter<ValueType, false> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& ) {}
ValueType interpret( cstring param_name, cstring source ) const
{
ValueType res;
if( !unit_test::utils::string_as<ValueType>( source, res ) )
BOOST_TEST_I_THROW( format_error( param_name ) << source <<
" can't be interpreted as value of parameter " << param_name << "." );
return res;
}
};
//____________________________________________________________________________//
template<>
struct value_interpreter<std::string, false> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& ) {}
std::string interpret( cstring, cstring source ) const
{
return std::string( source.begin(), source.size() );
}
};
//____________________________________________________________________________//
template<>
struct value_interpreter<cstring, false> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& ) {}
cstring interpret( cstring, cstring source ) const
{
return source;
}
};
//____________________________________________________________________________//
template<>
struct value_interpreter<bool, false> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& ) {}
bool interpret( cstring param_name, cstring source ) const
{
static cstring const s_YES( "YES" );
static cstring const s_Y( "Y" );
static cstring const s_NO( "NO" );
static cstring const s_N( "N" );
static cstring const s_TRUE( "TRUE" );
static cstring const s_FALSE( "FALSE" );
static cstring const s_one( "1" );
static cstring const s_zero( "0" );
source.trim();
if( source.is_empty() ||
case_ins_eq( source, s_YES ) ||
case_ins_eq( source, s_Y ) ||
case_ins_eq( source, s_one ) ||
case_ins_eq( source, s_TRUE ) )
return true;
if( case_ins_eq( source, s_NO ) ||
case_ins_eq( source, s_N ) ||
case_ins_eq( source, s_zero ) ||
case_ins_eq( source, s_FALSE ) )
return false;
BOOST_TEST_I_THROW( format_error( param_name ) << source << " can't be interpreted as bool value." );
}
};
//____________________________________________________________________________//
template<typename EnumType>
struct value_interpreter<EnumType, true> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& m )
#if defined(BOOST_TEST_CLA_NEW_API)
: m_name_to_value( m[enum_values<EnumType>::value] )
{
}
#else
{
std::vector<std::pair<cstring,EnumType> > const& values = m[enum_values<EnumType>::value];
m_name_to_value.insert( values.begin(), values.end() );
}
#endif
EnumType interpret( cstring param_name, cstring source ) const
{
typename std::map<cstring,EnumType>::const_iterator found = m_name_to_value.find( source );
BOOST_TEST_I_ASSRT( found != m_name_to_value.end(),
format_error( param_name ) << source <<
" is not a valid enumeration value name for parameter " << param_name << "." );
return found->second;
}
private:
// Data members
std::map<cstring,EnumType> m_name_to_value;
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** runtime::argument_factory ************** //
// ************************************************************************** //
template<typename ValueType, bool is_enum, bool repeatable>
class argument_factory;
//____________________________________________________________________________//
template<typename ValueType, bool is_enum>
class argument_factory<ValueType, is_enum, false> {
public:
template<typename Modifiers>
explicit argument_factory( Modifiers const& m )
: m_interpreter( m )
, m_optional_value( nfp::opt_get( m, optional_value, ValueType() ) )
, m_default_value( nfp::opt_get( m, default_value, ValueType() ) )
{
}
void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
{
store.set( param_name, source.empty() ? m_optional_value : m_interpreter.interpret( param_name, source ) );
}
void produce_default( cstring param_name, arguments_store& store ) const
{
store.set( param_name, m_default_value );
}
private:
// Data members
typedef value_interpreter<ValueType, is_enum> interp_t;
interp_t m_interpreter;
ValueType m_optional_value;
ValueType m_default_value;
};
//____________________________________________________________________________//
template<typename ValueType, bool is_enum>
class argument_factory<ValueType, is_enum, true> {
public:
template<typename Modifiers>
explicit argument_factory( Modifiers const& m )
: m_interpreter( m )
{
}
void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
{
ValueType value = m_interpreter.interpret( param_name, source );
if( store.has( param_name ) ) {
std::vector<ValueType>& values = store.get<std::vector<ValueType> >( param_name );
values.push_back( value );
}
else {
std::vector<ValueType> values( 1, value );
store.set( param_name, values );
}
}
void produce_default( cstring param_name, arguments_store& store ) const
{
store.set( param_name, std::vector<ValueType>() );
}
private:
// Data members
value_interpreter<ValueType, is_enum> m_interpreter;
};
//____________________________________________________________________________//
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP

View File

@@ -0,0 +1,106 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : defines facility to hide input traversing details
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
#define BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>
#include <cstring>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
namespace cla {
// ************************************************************************** //
// ************** runtime::cla::argv_traverser ************** //
// ************************************************************************** //
class argv_traverser {
typedef char const** argv_type;
public:
/// Constructs traverser based on argc/argv pair
/// argv is taken "by reference" and later can be
/// updated in remainder method
argv_traverser( int argc, argv_type argv )
: m_argc( argc )
, m_curr_token( 0 )
, m_token_size( 0 )
, m_argv( argv )
{
// save program name
save_token();
}
/// Returns new argc
int remainder()
{
return static_cast<int>(m_argc);
}
/// Returns true, if we reached end on input
bool eoi() const
{
return m_curr_token == m_argc;
}
/// Returns current token in the input
cstring current_token()
{
if( eoi() )
return cstring();
return cstring( m_argv[m_curr_token], m_token_size );
}
/// Saves current token for remainder
void save_token()
{
++m_curr_token;
if( !eoi() )
m_token_size = ::strlen( m_argv[m_curr_token] );
}
/// Commit current token and iterate to next one
void next_token()
{
if( !eoi() ) {
for( std::size_t i = m_curr_token; i < m_argc-1; ++i )
m_argv[i] = m_argv[i + 1];
--m_argc;
m_token_size = ::strlen( m_argv[m_curr_token] );
}
}
private:
// Data members
std::size_t m_argc; // total number of arguments
std::size_t m_curr_token; // current token index in argv
std::size_t m_token_size; // current token size
argv_type m_argv; // all arguments
};
} // namespace cla
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP

View File

@@ -0,0 +1,625 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief CLA parser
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
#define BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/utils/runtime/modifier.hpp>
#include <boost/test/utils/runtime/parameter.hpp>
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
// Boost.Test
#include <boost/test/utils/foreach.hpp>
#include <boost/test/utils/algorithm.hpp>
#include <boost/test/detail/throw_exception.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/algorithm/cxx11/all_of.hpp> // !! ?? unnecessary after cxx11
// STL
// !! ?? #include <unordered_set>
#include <set>
#include <iostream>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
namespace cla {
// ************************************************************************** //
// ************** runtime::cla::parameter_trie ************** //
// ************************************************************************** //
namespace rt_cla_detail {
struct parameter_trie;
typedef shared_ptr<parameter_trie> parameter_trie_ptr;
typedef std::map<char,parameter_trie_ptr> trie_per_char;
typedef std::vector<boost::reference_wrapper<parameter_cla_id const> > param_cla_id_list;
struct parameter_trie {
parameter_trie() : m_has_final_candidate( false ) {}
/// If subtrie corresponding to the char c exists returns it otherwise creates new
parameter_trie_ptr make_subtrie( char c )
{
trie_per_char::const_iterator it = m_subtrie.find( c );
if( it == m_subtrie.end() )
it = m_subtrie.insert( std::make_pair( c, parameter_trie_ptr( new parameter_trie ) ) ).first;
return it->second;
}
/// Creates series of sub-tries per characters in a string
parameter_trie_ptr make_subtrie( cstring s )
{
parameter_trie_ptr res;
BOOST_TEST_FOREACH( char, c, s )
res = (res ? res->make_subtrie( c ) : make_subtrie( c ));
return res;
}
/// Registers candidate parameter for this subtrie. If final, it needs to be unique
void add_candidate_id( parameter_cla_id const& param_id, basic_param_ptr param_candidate, bool final )
{
BOOST_TEST_I_ASSRT( !m_has_final_candidate && (!final || m_id_candidates.empty()),
conflicting_param() << "Parameter cla id " << param_id.m_tag << " conflicts with the "
<< "parameter cla id " << m_id_candidates.back().get().m_tag );
m_has_final_candidate = final;
m_id_candidates.push_back( ref(param_id) );
if( m_id_candidates.size() == 1 )
m_param_candidate = param_candidate;
else
m_param_candidate.reset();
}
/// Gets subtrie for specified char if present or nullptr otherwise
parameter_trie_ptr get_subtrie( char c ) const
{
trie_per_char::const_iterator it = m_subtrie.find( c );
return it != m_subtrie.end() ? it->second : parameter_trie_ptr();
}
// Data members
trie_per_char m_subtrie;
param_cla_id_list m_id_candidates;
basic_param_ptr m_param_candidate;
bool m_has_final_candidate;
};
// ************************************************************************** //
// ************** runtime::cla::report_foreing_token ************** //
// ************************************************************************** //
static void
report_foreing_token( cstring program_name, cstring token )
{
std::cerr << "Boost.Test WARNING: token \"" << token << "\" does not correspond to the Boost.Test argument \n"
<< " and should be placed after all Boost.Test arguments and the -- separator.\n"
<< " For example: " << program_name << " --random -- " << token << "\n";
}
} // namespace rt_cla_detail
// ************************************************************************** //
// ************** runtime::cla::parser ************** //
// ************************************************************************** //
class parser {
public:
/// Initializes a parser and builds internal trie representation used for
/// parsing based on the supplied parameters
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
template<typename Modifiers=nfp::no_params_type>
parser( parameters_store const& parameters, Modifiers const& m = nfp::no_params )
#else
template<typename Modifiers>
parser( parameters_store const& parameters, Modifiers const& m )
#endif
{
nfp::opt_assign( m_end_of_param_indicator, m, end_of_params );
nfp::opt_assign( m_negation_prefix, m, negation_prefix );
BOOST_TEST_I_ASSRT( algorithm::all_of( m_end_of_param_indicator.begin(),
m_end_of_param_indicator.end(),
parameter_cla_id::valid_prefix_char ),
invalid_cla_id() << "End of parameters indicator can only consist of prefix characters." );
BOOST_TEST_I_ASSRT( algorithm::all_of( m_negation_prefix.begin(),
m_negation_prefix.end(),
parameter_cla_id::valid_name_char ),
invalid_cla_id() << "Negation prefix can only consist of prefix characters." );
build_trie( parameters );
}
// input processing method
int
parse( int argc, char** argv, runtime::arguments_store& res )
{
// save program name for help message
m_program_name = argv[0];
cstring path_sep( "\\/" );
cstring::iterator it = unit_test::utils::find_last_of( m_program_name.begin(), m_program_name.end(),
path_sep.begin(), path_sep.end() );
if( it != m_program_name.end() )
m_program_name.trim_left( it + 1 );
// Set up the traverser
argv_traverser tr( argc, (char const**)argv );
// Loop till we reach end of input
while( !tr.eoi() ) {
cstring curr_token = tr.current_token();
cstring prefix;
cstring name;
cstring value_separator;
bool negative_form = false;
// Perform format validations and split the argument into prefix, name and separator
// False return value indicates end of params indicator is met
if( !validate_token_format( curr_token, prefix, name, value_separator, negative_form ) ) {
// get rid of "end of params" token
tr.next_token();
break;
}
// Locate trie corresponding to found prefix and skip it in the input
trie_ptr curr_trie = m_param_trie[prefix];
if( !curr_trie ) {
// format_error() << "Unrecognized parameter prefix in the argument " << tr.current_token()
rt_cla_detail::report_foreing_token( m_program_name, curr_token );
tr.save_token();
continue;
}
curr_token.trim_left( prefix.size() );
// Locate parameter based on a name and skip it in the input
locate_result locate_res = locate_parameter( curr_trie, name, curr_token );
parameter_cla_id const& found_id = locate_res.first;
basic_param_ptr found_param = locate_res.second;
if( negative_form ) {
BOOST_TEST_I_ASSRT( found_id.m_negatable,
format_error( found_param->p_name )
<< "Parameter tag " << found_id.m_tag << " is not negatable." );
curr_token.trim_left( m_negation_prefix.size() );
}
curr_token.trim_left( name.size() );
bool should_go_to_next = true;
cstring value;
// Skip validations if parameter has optional value and we are at the end of token
if( !value_separator.is_empty() || !found_param->p_has_optional_value ) {
// we are given a separator or there is no optional value
// Validate and skip value separator in the input
BOOST_TEST_I_ASSRT( found_id.m_value_separator == value_separator,
format_error( found_param->p_name )
<< "Invalid separator for the parameter "
<< found_param->p_name
<< " in the argument " << tr.current_token() );
curr_token.trim_left( value_separator.size() );
// Deduce value source
value = curr_token;
if( value.is_empty() ) {
tr.next_token();
value = tr.current_token();
}
BOOST_TEST_I_ASSRT( !value.is_empty(),
format_error( found_param->p_name )
<< "Missing an argument value for the parameter "
<< found_param->p_name
<< " in the argument " << tr.current_token() );
}
else if( (value_separator.is_empty() && found_id.m_value_separator.empty()) ) {
// Deduce value source
value = curr_token;
if( value.is_empty() ) {
tr.next_token(); // tokenization broke the value, we check the next one
if(!found_param->p_has_optional_value) {
// there is no separator and there is no optional value
// we look for the value on the next token
// example "-t XXXX" (no default)
// and we commit this value as being the passed value
value = tr.current_token();
}
else {
// there is no separator and the value is optional
// we check the next token
// example "-c" (defaults to true)
// and commit this as the value if this is not a token
cstring value_check = tr.current_token();
cstring prefix_test, name_test, value_separator_test;
bool negative_form_test;
if( validate_token_format( value_check, prefix_test, name_test, value_separator_test, negative_form_test )
&& m_param_trie[prefix_test]) {
// this is a token, we consume what we have
should_go_to_next = false;
}
else {
// this is a value, we commit it
value = value_check;
}
}
}
}
// Validate against argument duplication
BOOST_TEST_I_ASSRT( !res.has( found_param->p_name ) || found_param->p_repeatable,
duplicate_arg( found_param->p_name )
<< "Duplicate argument value for the parameter "
<< found_param->p_name
<< " in the argument " << tr.current_token() );
// Produce argument value
found_param->produce_argument( value, negative_form, res );
if(should_go_to_next) {
tr.next_token();
}
}
// generate the remainder and return it's size
return tr.remainder();
}
// help/usage/version
void
version( std::ostream& ostr )
{
ostr << "Boost.Test module ";
#if defined(BOOST_TEST_MODULE)
// we do not want to refer to the master test suite there
ostr << '\'' << BOOST_TEST_STRINGIZE( BOOST_TEST_MODULE ).trim( "\"" ) << "' ";
#endif
ostr << "in executable '" << m_program_name << "'\n";
ostr << "Compiled from Boost version "
<< BOOST_VERSION/100000 << "."
<< BOOST_VERSION/100 % 1000 << "."
<< BOOST_VERSION % 100 ;
ostr << " with ";
#if defined(BOOST_TEST_INCLUDED)
ostr << "header-only inclusion of";
#elif defined(BOOST_TEST_DYN_LINK)
ostr << "dynamic linking to";
#else
ostr << "static linking to";
#endif
ostr << " Boost.Test\n";
ostr << "- Compiler: " << BOOST_COMPILER << '\n'
<< "- Platform: " << BOOST_PLATFORM << '\n'
<< "- STL : " << BOOST_STDLIB;
ostr << std::endl;
}
void
usage(std::ostream& ostr,
cstring param_name = cstring(),
bool use_color = true)
{
namespace utils = unit_test::utils;
namespace ut_detail = unit_test::ut_detail;
if( !param_name.is_empty() ) {
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
param->usage( ostr, m_negation_prefix );
}
else {
ostr << "\n The program '" << m_program_name << "' is a Boost.Test module containing unit tests.";
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
ostr << "\n\n Usage\n ";
}
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
ostr << m_program_name << " [Boost.Test argument]... ";
}
if( !m_end_of_param_indicator.empty() ) {
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
ostr << '[' << m_end_of_param_indicator << " [custom test module argument]...]";
}
}
ostr << "\n\n Use\n ";
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
ostr << m_program_name << " --help";
}
ostr << "\n or ";
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
ostr << m_program_name << " --help=<parameter name>";
}
ostr << "\n for detailed help on Boost.Test parameters.\n";
}
void
help(std::ostream& ostr,
parameters_store const& parameters,
cstring param_name,
bool use_color = true)
{
namespace utils = unit_test::utils;
namespace ut_detail = unit_test::ut_detail;
if( !param_name.is_empty() ) {
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
param->help( ostr, m_negation_prefix, use_color);
return;
}
usage(ostr, cstring(), use_color);
ostr << "\n\n";
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
ostr << " Command line flags:\n";
}
runtime::commandline_pretty_print(
ostr,
" ",
"The command line flags of Boost.Test are listed below. "
"All parameters are optional. You can specify parameter value either "
"as a command line argument or as a value of its corresponding environment "
"variable. If a flag is specified as a command line argument and an environment variable "
"at the same time, the command line takes precedence. "
"The command line argument "
"support name guessing, and works with shorter names as long as those are not ambiguous."
);
if( !m_end_of_param_indicator.empty() ) {
ostr << "\n\n All the arguments after the '";
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
ostr << m_end_of_param_indicator;
}
ostr << "' are ignored by Boost.Test.";
}
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
ostr << "\n\n Environment variables:\n";
}
runtime::commandline_pretty_print(
ostr,
" ",
"Every argument listed below may also be set by a corresponding environment"
"variable. For an argument '--argument_x=<value>', the corresponding "
"environment variable is 'BOOST_TEST_ARGUMENT_X=value"
);
ostr << "\n\n The following parameters are supported:\n";
BOOST_TEST_FOREACH(
parameters_store::storage_type::value_type const&,
v,
parameters.all() )
{
basic_param_ptr param = v.second;
ostr << "\n";
param->usage( ostr, m_negation_prefix, use_color);
}
}
private:
typedef rt_cla_detail::parameter_trie_ptr trie_ptr;
typedef rt_cla_detail::trie_per_char trie_per_char;
typedef std::map<cstring,trie_ptr> str_to_trie;
void
build_trie( parameters_store const& parameters )
{
// Iterate over all parameters
BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, parameters.all() ) {
basic_param_ptr param = v.second;
// Register all parameter's ids in trie.
BOOST_TEST_FOREACH( parameter_cla_id const&, id, param->cla_ids() ) {
// This is the trie corresponding to the prefix.
trie_ptr next_trie = m_param_trie[id.m_prefix];
if( !next_trie )
next_trie = m_param_trie[id.m_prefix] = trie_ptr( new rt_cla_detail::parameter_trie );
// Build the trie, by following name's characters
// and register this parameter as candidate on each level
for( size_t index = 0; index < id.m_tag.size(); ++index ) {
next_trie = next_trie->make_subtrie( id.m_tag[index] );
next_trie->add_candidate_id( id, param, index == (id.m_tag.size() - 1) );
}
}
}
}
bool
validate_token_format( cstring token, cstring& prefix, cstring& name, cstring& separator, bool& negative_form )
{
// Match prefix
cstring::iterator it = token.begin();
while( it != token.end() && parameter_cla_id::valid_prefix_char( *it ) )
++it;
prefix.assign( token.begin(), it );
if( prefix.empty() )
return true;
// Match name
while( it != token.end() && parameter_cla_id::valid_name_char( *it ) )
++it;
name.assign( prefix.end(), it );
if( name.empty() ) {
if( prefix == m_end_of_param_indicator )
return false;
BOOST_TEST_I_THROW( format_error() << "Invalid format for an actual argument " << token );
}
// Match value separator
while( it != token.end() && parameter_cla_id::valid_separator_char( *it ) )
++it;
separator.assign( name.end(), it );
// Match negation prefix
negative_form = !m_negation_prefix.empty() && ( name.substr( 0, m_negation_prefix.size() ) == m_negation_prefix );
if( negative_form )
name.trim_left( m_negation_prefix.size() );
return true;
}
// C++03: cannot have references as types
typedef std::pair<parameter_cla_id, basic_param_ptr> locate_result;
locate_result
locate_parameter( trie_ptr curr_trie, cstring name, cstring token )
{
std::vector<trie_ptr> typo_candidates;
std::vector<trie_ptr> next_typo_candidates;
trie_ptr next_trie;
BOOST_TEST_FOREACH( char, c, name ) {
if( curr_trie ) {
// locate next subtrie corresponding to the char
next_trie = curr_trie->get_subtrie( c );
if( next_trie )
curr_trie = next_trie;
else {
// Initiate search for typo candicates. We will account for 'wrong char' typo
// 'missing char' typo and 'extra char' typo
BOOST_TEST_FOREACH( trie_per_char::value_type const&, typo_cand, curr_trie->m_subtrie ) {
// 'wrong char' typo
typo_candidates.push_back( typo_cand.second );
// 'missing char' typo
if( (next_trie = typo_cand.second->get_subtrie( c )) )
typo_candidates.push_back( next_trie );
}
// 'extra char' typo
typo_candidates.push_back( curr_trie );
curr_trie.reset();
}
}
else {
// go over existing typo candidates and see if they are still viable
BOOST_TEST_FOREACH( trie_ptr, typo_cand, typo_candidates ) {
trie_ptr next_typo_cand = typo_cand->get_subtrie( c );
if( next_typo_cand )
next_typo_candidates.push_back( next_typo_cand );
}
next_typo_candidates.swap( typo_candidates );
next_typo_candidates.clear();
}
}
if( !curr_trie ) {
std::vector<cstring> typo_candidate_names;
std::set<parameter_cla_id const*> unique_typo_candidate; // !! ?? unordered_set
typo_candidate_names.reserve( typo_candidates.size() );
// !! ?? unique_typo_candidate.reserve( typo_candidates.size() );
BOOST_TEST_FOREACH( trie_ptr, trie_cand, typo_candidates ) {
// avoid ambiguos candidate trie
if( trie_cand->m_id_candidates.size() > 1 )
continue;
BOOST_TEST_FOREACH( parameter_cla_id const&, param_cand, trie_cand->m_id_candidates ) {
if( !unique_typo_candidate.insert( &param_cand ).second )
continue;
typo_candidate_names.push_back( param_cand.m_tag );
}
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_TEST_I_THROW( unrecognized_param( std::move(typo_candidate_names) )
<< "An unrecognized parameter in the argument "
<< token );
#else
BOOST_TEST_I_THROW( unrecognized_param( typo_candidate_names )
<< "An unrecognized parameter in the argument "
<< token );
#endif
}
if( curr_trie->m_id_candidates.size() > 1 ) {
std::vector<cstring> amb_names;
BOOST_TEST_FOREACH( parameter_cla_id const&, param_id, curr_trie->m_id_candidates )
amb_names.push_back( param_id.m_tag );
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_TEST_I_THROW( ambiguous_param( std::move( amb_names ) )
<< "An ambiguous parameter name in the argument " << token );
#else
BOOST_TEST_I_THROW( ambiguous_param( amb_names )
<< "An ambiguous parameter name in the argument " << token );
#endif
}
return locate_result( curr_trie->m_id_candidates.back().get(), curr_trie->m_param_candidate );
}
// Data members
cstring m_program_name;
std::string m_end_of_param_indicator;
std::string m_negation_prefix;
str_to_trie m_param_trie;
};
} // namespace cla
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP

View File

@@ -0,0 +1,108 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : implements fetching absent parameter athuments from environment
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_ENV_FETCH_HPP
#define BOOST_TEST_UTILS_RUNTIME_ENV_FETCH_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/parameter.hpp>
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// C Runtime
#include <stdlib.h>
namespace boost {
namespace runtime {
namespace env {
namespace env_detail {
#ifndef UNDER_CE
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4996) // getenv
#endif
inline std::pair<cstring,bool>
sys_read_var( cstring var_name )
{
using namespace std;
char const* res = getenv( var_name.begin() );
return std::make_pair( cstring(res), res != NULL );
}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#else
inline std::pair<cstring,bool>
sys_read_var( cstring var_name )
{
return std::make_pair( cstring(), false );
}
#endif
//____________________________________________________________________________//
template<typename ReadFunc>
inline void
fetch_absent( parameters_store const& params, runtime::arguments_store& args, ReadFunc read_func )
{
BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, params.all() ) {
basic_param_ptr param = v.second;
if( args.has( param->p_name ) || param->p_env_var.empty() )
continue;
std::pair<cstring,bool> value = read_func( param->p_env_var );
if( !value.second )
continue;
// Validate against unexpected empty value
BOOST_TEST_I_ASSRT( !value.first.is_empty() || param->p_has_optional_value,
format_error( param->p_name )
<< "Missing an argument value for the parameter " << param->p_name
<< " in the environment." );
// Produce argument value
param->produce_argument( value.first, false, args );
}
}
//____________________________________________________________________________//
} // namespace env_detail
inline void
fetch_absent( parameters_store const& params, runtime::arguments_store& args )
{
env_detail::fetch_absent( params, args, &env_detail::sys_read_var );
}
} // namespace env
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_ENV_FETCH_HPP

View File

@@ -0,0 +1,195 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : defines runtime parameters setup error
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_INIT_ERROR_HPP
#define BOOST_TEST_UTILS_RUNTIME_INIT_ERROR_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>
// Boost.Test
#include <boost/test/utils/string_cast.hpp>
// Boost.Test
#include <boost/config.hpp>
// STL
#include <exception>
#include <vector>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
// ************************************************************************** //
// ************** runtime::param_error ************** //
// ************************************************************************** //
class BOOST_SYMBOL_VISIBLE param_error : public std::exception {
public:
~param_error() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}
const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
{
return msg.c_str();
}
cstring param_name;
std::string msg;
protected:
explicit param_error( cstring param_name_ ) : param_name( param_name_) {}
};
//____________________________________________________________________________//
class BOOST_SYMBOL_VISIBLE init_error : public param_error {
protected:
explicit init_error( cstring param_name ) : param_error( param_name ) {}
~init_error() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}
};
class BOOST_SYMBOL_VISIBLE input_error : public param_error {
protected:
explicit input_error( cstring param_name ) : param_error( param_name ) {}
~input_error() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}
};
//____________________________________________________________________________//
template<typename Derived, typename Base>
class BOOST_SYMBOL_VISIBLE specific_param_error : public Base {
protected:
explicit specific_param_error( cstring param_name ) : Base( param_name ) {}
~specific_param_error() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}
public:
//____________________________________________________________________________//
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_REF_QUALIFIERS)
Derived operator<<(char const* val) &&
{
this->msg.append( val );
return static_cast<Derived&&>(*this);
}
//____________________________________________________________________________//
template<typename T>
Derived operator<<(T const& val) &&
{
this->msg.append( unit_test::utils::string_cast( val ) );
return static_cast<Derived&&>(*this);
}
//____________________________________________________________________________//
#else
Derived const& operator<<(char const* val) const
{
const_cast<specific_param_error<Derived, Base>&>(*this).msg.append( val );
return static_cast<Derived const&>(*this);
}
//____________________________________________________________________________//
template<typename T>
Derived const& operator<<(T const& val) const
{
const_cast<specific_param_error<Derived, Base>&>(*this).msg.append( unit_test::utils::string_cast( val ) );
return static_cast<Derived const&>(*this);
}
//____________________________________________________________________________//
#endif
};
// ************************************************************************** //
// ************** specific exception types ************** //
// ************************************************************************** //
#define SPECIFIC_EX_TYPE( type, base ) \
class BOOST_SYMBOL_VISIBLE type : public specific_param_error<type,base> { \
public: \
explicit type( cstring param_name = cstring() ) \
: specific_param_error<type,base>( param_name ) \
{} \
} \
/**/
SPECIFIC_EX_TYPE( invalid_cla_id, init_error );
SPECIFIC_EX_TYPE( duplicate_param, init_error );
SPECIFIC_EX_TYPE( conflicting_param, init_error );
SPECIFIC_EX_TYPE( unknown_param, init_error );
SPECIFIC_EX_TYPE( access_to_missing_argument, init_error );
SPECIFIC_EX_TYPE( arg_type_mismatch, init_error );
SPECIFIC_EX_TYPE( invalid_param_spec, init_error );
SPECIFIC_EX_TYPE( format_error, input_error );
SPECIFIC_EX_TYPE( duplicate_arg, input_error );
SPECIFIC_EX_TYPE( missing_req_arg, input_error );
#undef SPECIFIC_EX_TYPE
class BOOST_SYMBOL_VISIBLE ambiguous_param : public specific_param_error<ambiguous_param, input_error> {
public:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
explicit ambiguous_param( std::vector<cstring>&& amb_candidates )
: specific_param_error<ambiguous_param,input_error>( "" )
, m_amb_candidates( std::move( amb_candidates ) ) {}
#else
explicit ambiguous_param( std::vector<cstring> const& amb_candidates )
: specific_param_error<ambiguous_param,input_error>( "" )
, m_amb_candidates( amb_candidates ) {}
#endif
~ambiguous_param() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}
std::vector<cstring> m_amb_candidates;
};
class BOOST_SYMBOL_VISIBLE unrecognized_param : public specific_param_error<unrecognized_param, input_error> {
public:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
explicit unrecognized_param( std::vector<cstring>&& type_candidates )
: specific_param_error<unrecognized_param,input_error>( "" )
, m_typo_candidates( std::move( type_candidates ) ) {}
#else
explicit unrecognized_param( std::vector<cstring> const& type_candidates )
: specific_param_error<unrecognized_param,input_error>( "" )
, m_typo_candidates( type_candidates ) {}
#endif
~unrecognized_param() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}
std::vector<cstring> m_typo_candidates;
};
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_INIT_ERROR_HPP

View File

@@ -0,0 +1,56 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : runtime parameters initialization final step
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_FINALIZE_HPP
#define BOOST_TEST_UTILS_RUNTIME_FINALIZE_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/parameter.hpp>
#include <boost/test/utils/runtime/argument.hpp>
// Boost.Test
#include <boost/test/utils/foreach.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
inline void
finalize_arguments( parameters_store const& params, runtime::arguments_store& args )
{
BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, params.all() ) {
basic_param_ptr param = v.second;
if( !args.has( param->p_name ) ) {
if( param->p_has_default_value )
param->produce_default( args );
if( !args.has( param->p_name ) ) {
BOOST_TEST_I_ASSRT( param->p_optional,
missing_req_arg( param->p_name ) << "Missing argument for required parameter " << param->p_name << "." );
}
}
if( args.has( param->p_name ) && !!param->p_callback )
param->p_callback( param->p_name );
}
}
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_FINALIZE_HPP

View File

@@ -0,0 +1,45 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : runtime parameters forward declaration
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_FWD_HPP
#define BOOST_TEST_UTILS_RUNTIME_FWD_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/basic_cstring/io.hpp> // operator<<(boost::runtime::cstring)
// Boost
#include <boost/shared_ptr.hpp>
// STL
#include <map>
namespace boost {
namespace runtime {
typedef unit_test::const_string cstring;
class argument;
typedef shared_ptr<argument> argument_ptr;
template<typename T> class typed_argument;
class basic_param;
typedef shared_ptr<basic_param> basic_param_ptr;
} // namespace runtime
} // namespace boost
#endif // BOOST_TEST_UTILS_RUNTIME_FWD_HPP

View File

@@ -0,0 +1,107 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : parameter modifiers
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_MODIFIER_HPP
#define BOOST_TEST_UTILS_RUNTIME_MODIFIER_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>
// Boost.Test
#include <boost/test/utils/named_params.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// New CLA API available only for some C++11 compilers
#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) \
&& !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) \
&& !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) \
&& !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
#define BOOST_TEST_CLA_NEW_API
#endif
namespace boost {
namespace runtime {
// ************************************************************************** //
// ************** environment variable modifiers ************** //
// ************************************************************************** //
namespace {
#ifdef BOOST_TEST_CLA_NEW_API
auto const& description = unit_test::static_constant<nfp::typed_keyword<cstring,struct description_t>>::value;
auto const& help = unit_test::static_constant<nfp::typed_keyword<cstring,struct help_t>>::value;
auto const& env_var = unit_test::static_constant<nfp::typed_keyword<cstring,struct env_var_t>>::value;
auto const& end_of_params = unit_test::static_constant<nfp::typed_keyword<cstring,struct end_of_params_t>>::value;
auto const& negation_prefix = unit_test::static_constant<nfp::typed_keyword<cstring,struct neg_prefix_t>>::value;
auto const& value_hint = unit_test::static_constant<nfp::typed_keyword<cstring,struct value_hint_t>>::value;
auto const& optional_value = unit_test::static_constant<nfp::keyword<struct optional_value_t>>::value;
auto const& default_value = unit_test::static_constant<nfp::keyword<struct default_value_t>>::value;
auto const& callback = unit_test::static_constant<nfp::keyword<struct callback_t>>::value;
template<typename EnumType>
using enum_values = unit_test::static_constant<
nfp::typed_keyword<std::initializer_list<std::pair<const cstring,EnumType>>, struct enum_values_t>
>;
#else
nfp::typed_keyword<cstring,struct description_t> description;
nfp::typed_keyword<cstring,struct help_t> help;
nfp::typed_keyword<cstring,struct env_var_t> env_var;
nfp::typed_keyword<cstring,struct end_of_params_t> end_of_params;
nfp::typed_keyword<cstring,struct neg_prefix_t> negation_prefix;
nfp::typed_keyword<cstring,struct value_hint_t> value_hint;
nfp::keyword<struct optional_value_t> optional_value;
nfp::keyword<struct default_value_t> default_value;
nfp::keyword<struct callback_t> callback;
template<typename EnumType>
struct enum_values_list {
typedef std::pair<cstring,EnumType> ElemT;
typedef std::vector<ElemT> ValuesT;
enum_values_list const&
operator()( cstring k, EnumType v ) const
{
const_cast<enum_values_list*>(this)->m_values.push_back( ElemT( k, v ) );
return *this;
}
operator ValuesT const&() const { return m_values; }
private:
ValuesT m_values;
};
template<typename EnumType>
struct enum_values : unit_test::static_constant<
nfp::typed_keyword<enum_values_list<EnumType>, struct enum_values_t> >
{
};
#endif
} // local namespace
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_MODIFIER_HPP

View File

@@ -0,0 +1,526 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : formal parameter definition
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_PARAMETER_HPP
#define BOOST_TEST_UTILS_RUNTIME_PARAMETER_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/utils/runtime/modifier.hpp>
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/utils/runtime/argument_factory.hpp>
// Boost.Test
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/foreach.hpp>
#include <boost/test/utils/setcolor.hpp>
// Boost
#include <boost/function.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>
// STL
#include <algorithm>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
inline
std::ostream& commandline_pretty_print(
std::ostream& ostr,
std::string const& prefix,
std::string const& to_print) {
const int split_at = 80;
std::string::size_type current = 0;
while(current < to_print.size()) {
// discards spaces at the beginning
std::string::size_type startpos = to_print.find_first_not_of(" \t\n", current);
current += startpos - current;
bool has_more_lines = (current + split_at) < to_print.size();
if(has_more_lines) {
std::string::size_type endpos = to_print.find_last_of(" \t\n", current + split_at);
std::string sub(to_print.substr(current, endpos - current));
ostr << prefix << sub;
ostr << "\n";
current += endpos - current;
}
else
{
ostr << prefix << to_print.substr(current, split_at);
current += split_at;
}
}
return ostr;
}
// ************************************************************************** //
// ************** runtime::parameter_cla_id ************** //
// ************************************************************************** //
// set of attributes identifying the parameter in the command line
struct parameter_cla_id {
parameter_cla_id( cstring prefix, cstring tag, cstring value_separator, bool negatable )
: m_prefix( prefix.begin(), prefix.size() )
, m_tag( tag.begin(), tag.size() )
, m_value_separator( value_separator.begin(), value_separator.size() )
, m_negatable( negatable )
{
BOOST_TEST_I_ASSRT( algorithm::all_of( m_prefix.begin(), m_prefix.end(), valid_prefix_char ),
invalid_cla_id() << "Parameter " << m_tag
<< " has invalid characters in prefix." );
BOOST_TEST_I_ASSRT( algorithm::all_of( m_tag.begin(), m_tag.end(), valid_name_char ),
invalid_cla_id() << "Parameter " << m_tag
<< " has invalid characters in name." );
BOOST_TEST_I_ASSRT( algorithm::all_of( m_value_separator.begin(), m_value_separator.end(), valid_separator_char ),
invalid_cla_id() << "Parameter " << m_tag
<< " has invalid characters in value separator." );
}
static bool valid_prefix_char( char c )
{
return c == '-' || c == '/' ;
}
static bool valid_separator_char( char c )
{
return c == '=' || c == ':' || c == ' ' || c == '\0';
}
static bool valid_name_char( char c )
{
return std::isalnum( c ) || c == '+' || c == '_' || c == '?';
}
std::string m_prefix;
std::string m_tag;
std::string m_value_separator;
bool m_negatable;
};
typedef std::vector<parameter_cla_id> param_cla_ids;
// ************************************************************************** //
// ************** runtime::basic_param ************** //
// ************************************************************************** //
cstring const help_prefix("////");
class basic_param {
typedef function<void (cstring)> callback_type;
typedef unit_test::readwrite_property<bool> bool_property;
protected:
/// Constructor with modifiers
template<typename Modifiers>
basic_param( cstring name, bool is_optional, bool is_repeatable, Modifiers const& m )
: p_name( name.begin(), name.end() )
, p_description( nfp::opt_get( m, description, std::string() ) )
, p_help( nfp::opt_get( m, runtime::help, std::string() ) )
, p_env_var( nfp::opt_get( m, env_var, std::string() ) )
, p_value_hint( nfp::opt_get( m, value_hint, std::string() ) )
, p_optional( is_optional )
, p_repeatable( is_repeatable )
, p_has_optional_value( m.has( optional_value ) )
, p_has_default_value( m.has( default_value ) || is_repeatable )
, p_callback( nfp::opt_get( m, callback, callback_type() ) )
{
add_cla_id( help_prefix, name, ":" );
}
public:
virtual ~basic_param() {}
// Pubic properties
std::string const p_name;
std::string const p_description;
std::string const p_help;
std::string const p_env_var;
std::string const p_value_hint;
bool const p_optional;
bool const p_repeatable;
bool_property p_has_optional_value;
bool_property p_has_default_value;
callback_type const p_callback;
/// interface for cloning typed parameters
virtual basic_param_ptr clone() const = 0;
/// Access methods
param_cla_ids const& cla_ids() const { return m_cla_ids; }
void add_cla_id( cstring prefix, cstring tag, cstring value_separator )
{
add_cla_id_impl( prefix, tag, value_separator, false, true );
}
/// interface for producing argument values for this parameter
virtual void produce_argument( cstring token, bool negative_form, arguments_store& store ) const = 0;
virtual void produce_default( arguments_store& store ) const = 0;
/// interfaces for help message reporting
virtual void usage( std::ostream& ostr, cstring negation_prefix_, bool use_color = true )
{
namespace utils = unit_test::utils;
namespace ut_detail = unit_test::ut_detail;
//
ostr << " ";
{
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
ostr << p_name;
}
ostr << '\n';
if( !p_description.empty() ) {
commandline_pretty_print(ostr, " ", p_description) << '\n';
}
BOOST_TEST_FOREACH( parameter_cla_id const&, id, cla_ids() ) {
if( id.m_prefix == help_prefix )
continue;
ostr << " " << id.m_prefix;
if( id.m_negatable )
cla_name_help( ostr, id.m_tag, negation_prefix_, use_color );
else
cla_name_help( ostr, id.m_tag, "", use_color );
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
bool optional_value_ = false;
if( p_has_optional_value ) {
optional_value_ = true;
ostr << '[';
}
if( id.m_value_separator.empty() )
ostr << ' ';
else {
ostr << id.m_value_separator;
}
value_help( ostr );
if( optional_value_ )
ostr << ']';
ostr << '\n';
}
}
virtual void help( std::ostream& ostr, cstring negation_prefix_, bool use_color = true )
{
usage( ostr, negation_prefix_, use_color );
if( !p_help.empty() ) {
ostr << '\n';
commandline_pretty_print(ostr, " ", p_help);
}
}
protected:
void add_cla_id_impl( cstring prefix,
cstring tag,
cstring value_separator,
bool negatable,
bool validate_value_separator )
{
BOOST_TEST_I_ASSRT( !tag.is_empty(),
invalid_cla_id() << "Parameter can't have an empty name." );
BOOST_TEST_I_ASSRT( !prefix.is_empty(),
invalid_cla_id() << "Parameter " << tag
<< " can't have an empty prefix." );
BOOST_TEST_I_ASSRT( !value_separator.is_empty(),
invalid_cla_id() << "Parameter " << tag
<< " can't have an empty value separator." );
// We trim value separator from all the spaces, so token end will indicate separator
value_separator.trim();
BOOST_TEST_I_ASSRT( !validate_value_separator || !value_separator.is_empty() || !p_has_optional_value,
invalid_cla_id() << "Parameter " << tag
<< " with optional value attribute can't use space as value separator." );
m_cla_ids.push_back( parameter_cla_id( prefix, tag, value_separator, negatable ) );
}
private:
/// interface for usage/help customization
virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring /*negation_prefix_*/, bool /*use_color*/ = true) const
{
ostr << cla_tag;
}
virtual void value_help( std::ostream& ostr ) const
{
if( p_value_hint.empty() )
ostr << "<value>";
else
ostr << p_value_hint;
}
// Data members
param_cla_ids m_cla_ids;
};
// ************************************************************************** //
// ************** runtime::parameter ************** //
// ************************************************************************** //
enum args_amount {
OPTIONAL_PARAM, // 0-1
REQUIRED_PARAM, // exactly 1
REPEATABLE_PARAM // 0-N
};
//____________________________________________________________________________//
template<typename ValueType, args_amount a = runtime::OPTIONAL_PARAM, bool is_enum = false>
class parameter : public basic_param {
public:
/// Constructor with modifiers
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
template<typename Modifiers=nfp::no_params_type>
parameter( cstring name, Modifiers const& m = nfp::no_params )
#else
template<typename Modifiers>
parameter( cstring name, Modifiers const& m )
#endif
: basic_param( name, a != runtime::REQUIRED_PARAM, a == runtime::REPEATABLE_PARAM, m )
, m_arg_factory( m )
{
BOOST_TEST_I_ASSRT( !m.has( default_value ) || a == runtime::OPTIONAL_PARAM,
invalid_param_spec() << "Parameter " << name
<< " is not optional and can't have default_value." );
BOOST_TEST_I_ASSRT( !m.has( optional_value ) || !this->p_repeatable,
invalid_param_spec() << "Parameter " << name
<< " is repeatable and can't have optional_value." );
}
private:
basic_param_ptr clone() const BOOST_OVERRIDE
{
return basic_param_ptr( new parameter( *this ) );
}
void produce_argument( cstring token, bool , arguments_store& store ) const BOOST_OVERRIDE
{
m_arg_factory.produce_argument( token, this->p_name, store );
}
void produce_default( arguments_store& store ) const BOOST_OVERRIDE
{
if( !this->p_has_default_value )
return;
m_arg_factory.produce_default( this->p_name, store );
}
// Data members
typedef argument_factory<ValueType, is_enum, a == runtime::REPEATABLE_PARAM> factory_t;
factory_t m_arg_factory;
};
//____________________________________________________________________________//
class option : public basic_param {
public:
/// Constructor with modifiers
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
template<typename Modifiers=nfp::no_params_type>
option( cstring name, Modifiers const& m = nfp::no_params )
#else
template<typename Modifiers>
option( cstring name, Modifiers const& m )
#endif
: basic_param( name, true, false, nfp::opt_append( nfp::opt_append( m, optional_value = true), default_value = false) )
, m_arg_factory( nfp::opt_append( nfp::opt_append( m, optional_value = true), default_value = false) )
{
}
void add_cla_id( cstring prefix, cstring tag, cstring value_separator, bool negatable = false )
{
add_cla_id_impl( prefix, tag, value_separator, negatable, false );
}
private:
basic_param_ptr clone() const BOOST_OVERRIDE
{
return basic_param_ptr( new option( *this ) );
}
void produce_argument( cstring token, bool negative_form, arguments_store& store ) const BOOST_OVERRIDE
{
if( token.empty() )
store.set( p_name, !negative_form );
else {
BOOST_TEST_I_ASSRT( !negative_form,
format_error( p_name ) << "Can't set value to negative form of the argument." );
m_arg_factory.produce_argument( token, p_name, store );
}
}
void produce_default( arguments_store& store ) const BOOST_OVERRIDE
{
m_arg_factory.produce_default( p_name, store );
}
void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring negation_prefix_, bool use_color = true ) const BOOST_OVERRIDE
{
namespace utils = unit_test::utils;
namespace ut_detail = unit_test::ut_detail;
if( !negation_prefix_.is_empty() ) {
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
ostr << '[' << negation_prefix_ << ']';
}
ostr << cla_tag;
}
void value_help( std::ostream& ostr ) const BOOST_OVERRIDE
{
if( p_value_hint.empty() )
ostr << "<boolean value>";
else
ostr << p_value_hint;
}
// Data members
typedef argument_factory<bool, false, false> factory_t;
factory_t m_arg_factory;
};
//____________________________________________________________________________//
template<typename EnumType, args_amount a = runtime::OPTIONAL_PARAM>
class enum_parameter : public parameter<EnumType, a, true> {
typedef parameter<EnumType, a, true> base;
public:
/// Constructor with modifiers
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
template<typename Modifiers=nfp::no_params_type>
enum_parameter( cstring name, Modifiers const& m = nfp::no_params )
#else
template<typename Modifiers>
enum_parameter( cstring name, Modifiers const& m )
#endif
: base( name, m )
{
#ifdef BOOST_TEST_CLA_NEW_API
auto const& values = m[enum_values<EnumType>::value];
auto it = values.begin();
#else
std::vector<std::pair<cstring, EnumType> > const& values = m[enum_values<EnumType>::value];
typename std::vector<std::pair<cstring, EnumType> >::const_iterator it = values.begin();
#endif
while( it != values.end() ) {
m_valid_names.push_back( it->first );
++it;
}
}
private:
basic_param_ptr clone() const BOOST_OVERRIDE
{
return basic_param_ptr( new enum_parameter( *this ) );
}
void value_help( std::ostream& ostr ) const BOOST_OVERRIDE
{
if( this->p_value_hint.empty() ) {
ostr << "<";
bool first = true;
BOOST_TEST_FOREACH( cstring, name, m_valid_names ) {
if( first )
first = false;
else
ostr << '|';
ostr << name;
}
ostr << ">";
}
else
ostr << this->p_value_hint;
}
// Data members
std::vector<cstring> m_valid_names;
};
// ************************************************************************** //
// ************** runtime::parameters_store ************** //
// ************************************************************************** //
class parameters_store {
struct lg_compare {
bool operator()( cstring lh, cstring rh ) const
{
return std::lexicographical_compare(lh.begin(), lh.end(),
rh.begin(), rh.end());
}
};
public:
typedef std::map<cstring, basic_param_ptr, lg_compare> storage_type;
/// Adds parameter into the persistent store
void add( basic_param const& in )
{
basic_param_ptr p = in.clone();
BOOST_TEST_I_ASSRT( m_parameters.insert( std::make_pair( cstring(p->p_name), p ) ).second,
duplicate_param() << "Parameter " << p->p_name << " is duplicate." );
}
/// Returns true if there is no parameters registered
bool is_empty() const { return m_parameters.empty(); }
/// Returns map of all the registered parameter
storage_type const& all() const { return m_parameters; }
/// Returns true if parameter with specified name is registered
bool has( cstring name ) const
{
return m_parameters.find( name ) != m_parameters.end();
}
/// Returns map of all the registered parameter
basic_param_ptr get( cstring name ) const
{
storage_type::const_iterator const& found = m_parameters.find( name );
BOOST_TEST_I_ASSRT( found != m_parameters.end(),
unknown_param() << "Parameter " << name << " is unknown." );
return found->second;
}
private:
// Data members
storage_type m_parameters;
};
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_PARAMETER_HPP

View File

@@ -0,0 +1,351 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : contains definition for setcolor iostream manipulator
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_SETCOLOR_HPP
#define BOOST_TEST_UTILS_SETCOLOR_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/core/ignore_unused.hpp>
// STL
#include <iostream>
#include <cstdio>
#include <cassert>
#include <boost/test/detail/suppress_warnings.hpp>
#ifdef _WIN32
#include <windows.h>
#if defined(__MINGW32__) && !defined(COMMON_LVB_UNDERSCORE)
// mingw badly mimicking windows.h
#define COMMON_LVB_UNDERSCORE 0x8000
#endif
#endif
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace utils {
// ************************************************************************** //
// ************** term_attr ************** //
// ************************************************************************** //
struct term_attr { enum _ {
NORMAL = 0,
BRIGHT = 1,
DIM = 2,
UNDERLINE = 4,
BLINK = 5,
REVERSE = 7,
CROSSOUT = 9
}; };
// ************************************************************************** //
// ************** term_color ************** //
// ************************************************************************** //
struct term_color { enum _ {
BLACK = 0,
RED = 1,
GREEN = 2,
YELLOW = 3,
BLUE = 4,
MAGENTA = 5,
CYAN = 6,
WHITE = 7,
ORIGINAL = 9
}; };
// ************************************************************************** //
// ************** setcolor ************** //
// ************************************************************************** //
#ifndef _WIN32
class setcolor {
public:
typedef int state;
// Constructor
explicit setcolor( bool is_color_output = false,
term_attr::_ attr = term_attr::NORMAL,
term_color::_ fg = term_color::ORIGINAL,
term_color::_ bg = term_color::ORIGINAL,
state* /* unused */= NULL)
: m_is_color_output(is_color_output)
{
m_command_size = std::sprintf( m_control_command, "%c[%c;3%c;4%cm",
0x1B,
static_cast<char>(attr + '0'),
static_cast<char>(fg + '0'),
static_cast<char>(bg + '0'));
}
explicit setcolor(bool is_color_output,
state* /* unused */)
: m_is_color_output(is_color_output)
{
m_command_size = std::sprintf(m_control_command, "%c[%c;3%c;4%cm",
0x1B,
static_cast<char>(term_attr::NORMAL + '0'),
static_cast<char>(term_color::ORIGINAL + '0'),
static_cast<char>(term_color::ORIGINAL + '0'));
}
friend std::ostream&
operator<<( std::ostream& os, setcolor const& sc )
{
if (sc.m_is_color_output && (&os == &std::cout || &os == &std::cerr)) {
return os.write( sc.m_control_command, sc.m_command_size );
}
return os;
}
private:
// Data members
bool m_is_color_output;
char m_control_command[13];
int m_command_size;
};
#else
class setcolor {
protected:
void set_console_color(std::ostream& os, WORD *attributes = NULL) const {
if (!m_is_color_output || m_state_saved) {
return;
}
DWORD console_type;
if (&os == &std::cout) {
console_type = STD_OUTPUT_HANDLE;
}
else if (&os == &std::cerr) {
console_type = STD_ERROR_HANDLE;
}
else {
return;
}
HANDLE hConsole = GetStdHandle(console_type);
if(hConsole == INVALID_HANDLE_VALUE || hConsole == NULL )
return;
state console_attributes;
if(attributes != NULL || (m_restore_state && m_s)) {
if (attributes != NULL) {
console_attributes = *attributes;
}
else {
console_attributes = *m_s;
*m_s = state();
}
SetConsoleTextAttribute(hConsole, console_attributes);
return;
}
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
console_attributes = consoleInfo.wAttributes;
if (!m_state_saved && m_s) {
assert(!m_restore_state);
// we can save the state only the first time this object is used
// for modifying the console.
*m_s = console_attributes;
m_state_saved = true;
}
WORD fg_attr = 0;
switch(m_fg)
{
case term_color::WHITE:
fg_attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
break;
case term_color::BLACK:
fg_attr = 0;
break;
case term_color::RED:
fg_attr = FOREGROUND_RED;
break;
case term_color::GREEN:
fg_attr = FOREGROUND_GREEN;
break;
case term_color::CYAN:
fg_attr = FOREGROUND_GREEN | FOREGROUND_BLUE;
break;
case term_color::MAGENTA:
fg_attr = FOREGROUND_RED | FOREGROUND_BLUE;
break;
case term_color::BLUE:
fg_attr = FOREGROUND_BLUE;
break;
case term_color::YELLOW:
fg_attr = FOREGROUND_RED | FOREGROUND_GREEN;
break;
case term_color::ORIGINAL:
default:
fg_attr = console_attributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
break;
}
WORD bg_attr = 0;
switch(m_bg)
{
case term_color::BLACK:
bg_attr = 0;
break;
case term_color::WHITE:
bg_attr = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
break;
case term_color::RED:
bg_attr = BACKGROUND_RED;
break;
case term_color::GREEN:
bg_attr = BACKGROUND_GREEN;
break;
case term_color::BLUE:
bg_attr = BACKGROUND_BLUE;
break;
case term_color::ORIGINAL:
default:
bg_attr = console_attributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
break;
}
WORD text_attr = 0;
switch(m_attr)
{
case term_attr::BRIGHT:
text_attr = FOREGROUND_INTENSITY;
break;
case term_attr::UNDERLINE:
text_attr = COMMON_LVB_UNDERSCORE;
break;
default:
break;
}
SetConsoleTextAttribute(hConsole, fg_attr | bg_attr | text_attr);
return;
}
public:
typedef WORD state;
// Constructor
explicit setcolor(
bool is_color_output = false,
term_attr::_ attr = term_attr::NORMAL,
term_color::_ fg = term_color::ORIGINAL,
term_color::_ bg = term_color::ORIGINAL,
state* s = NULL)
: m_is_color_output(is_color_output)
, m_attr(attr)
, m_fg(fg)
, m_bg(bg)
, m_s(s)
, m_restore_state(false)
, m_state_saved(false)
{}
explicit setcolor(
bool is_color_output,
state* s)
: m_is_color_output(is_color_output)
, m_attr(term_attr::NORMAL)
, m_fg(term_color::ORIGINAL)
, m_bg(term_color::ORIGINAL)
, m_s(s)
, m_restore_state(true)
, m_state_saved(false)
{}
friend std::ostream&
operator<<( std::ostream& os, setcolor const& sc )
{
sc.set_console_color(os);
return os;
}
private:
bool m_is_color_output;
term_attr::_ m_attr;
term_color::_ m_fg;
term_color::_ m_bg;
state* m_s;
// indicates that the instance has been initialized to restore a previously
// stored state
bool m_restore_state;
// indicates the first time we pull and set the console information.
mutable bool m_state_saved;
};
#endif
// ************************************************************************** //
// ************** scope_setcolor ************** //
// ************************************************************************** //
struct scope_setcolor {
scope_setcolor()
: m_os( 0 )
, m_state()
, m_is_color_output(false)
{}
explicit scope_setcolor(
bool is_color_output,
std::ostream& os,
term_attr::_ attr = term_attr::NORMAL,
term_color::_ fg = term_color::ORIGINAL,
term_color::_ bg = term_color::ORIGINAL )
: m_os( &os )
, m_is_color_output(is_color_output)
{
os << setcolor(is_color_output, attr, fg, bg, &m_state);
}
~scope_setcolor()
{
if (m_os) {
*m_os << setcolor(m_is_color_output, &m_state);
}
}
private:
scope_setcolor(const scope_setcolor& r);
scope_setcolor& operator=(const scope_setcolor& r);
// Data members
std::ostream* m_os;
setcolor::state m_state;
bool m_is_color_output;
};
#define BOOST_TEST_SCOPE_SETCOLOR( is_color_output, os, attr, color ) \
utils::scope_setcolor const sc(is_color_output, os, utils::attr, utils::color); \
boost::ignore_unused( sc ) \
/**/
} // namespace utils
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_SETCOLOR_HPP

View File

@@ -0,0 +1,69 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : trivial utility to cast to/from strings
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_STRING_CAST_HPP
#define BOOST_TEST_UTILS_STRING_CAST_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// STL
#include <sstream>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace utils {
// ************************************************************************** //
// ************** string_cast ************** //
// ************************************************************************** //
template<typename T>
inline std::string
string_cast( T const& t )
{
std::ostringstream buff;
buff << t;
return buff.str();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** string_as ************** //
// ************************************************************************** //
template<typename T>
inline bool
string_as( const_string str, T& res )
{
std::istringstream buff( std::string( str.begin(), str.end() ) );
buff >> res;
return !buff.fail() && buff.eof();
}
//____________________________________________________________________________//
} // namespace utils
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_STRING_CAST_HPP

View File

@@ -0,0 +1,165 @@
// (C) Copyright Raffi Enficiaud 2019.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// Description : timer and elapsed types
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_TIMER_HPP
#define BOOST_TEST_UTILS_TIMER_HPP
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <utility>
#include <ctime>
# if defined(_WIN32) || defined(__CYGWIN__)
# define BOOST_TEST_TIMER_WINDOWS_API
# elif defined(__MACH__) && defined(__APPLE__)// && !defined(CLOCK_MONOTONIC)
# // we compile for all macs the same, CLOCK_MONOTONIC introduced in 10.12
# define BOOST_TEST_TIMER_MACH_API
# else
# define BOOST_TEST_TIMER_POSIX_API
# if !defined(CLOCK_MONOTONIC)
# error "CLOCK_MONOTONIC not defined"
# endif
# endif
# if defined(BOOST_TEST_TIMER_WINDOWS_API)
# include <windows.h>
# elif defined(BOOST_TEST_TIMER_MACH_API)
# include <mach/mach_time.h>
//# include <mach/mach.h> /* host_get_clock_service, mach_... */
# else
# include <sys/time.h>
# endif
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::clock_t; using ::clock; }
# endif
namespace boost {
namespace unit_test {
namespace timer {
struct elapsed_time
{
typedef boost::int_least64_t nanosecond_type;
nanosecond_type wall;
nanosecond_type system;
void clear() {
wall = 0;
system = 0;
}
};
inline double
microsecond_wall_time( elapsed_time const& elapsed )
{
return elapsed.wall / 1E3;
}
inline double
second_wall_time( elapsed_time const& elapsed )
{
return elapsed.wall / 1E9;
}
namespace details {
#if defined(BOOST_TEST_TIMER_WINDOWS_API)
elapsed_time::nanosecond_type get_tick_freq() {
LARGE_INTEGER freq;
::QueryPerformanceFrequency( &freq );
return static_cast<elapsed_time::nanosecond_type>(freq.QuadPart);
}
#elif defined(BOOST_TEST_TIMER_MACH_API)
std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type> get_time_base() {
mach_timebase_info_data_t timebase;
if(mach_timebase_info(&timebase) == 0)
return std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type>(timebase.numer, timebase.denom);
return std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type>(0, 1);
}
#endif
}
//! Simple timing class
//!
//! This class measures the wall clock time.
class timer
{
public:
timer()
{
restart();
}
void restart()
{
_start_time_clock = std::clock();
#if defined(BOOST_TEST_TIMER_WINDOWS_API)
::QueryPerformanceCounter(&_start_time_wall);
#elif defined(BOOST_TEST_TIMER_MACH_API)
_start_time_wall = mach_absolute_time();
#else
if( ::clock_gettime( CLOCK_MONOTONIC, &_start_time_wall ) != 0 )
{
_start_time_wall.tv_nsec = -1;
_start_time_wall.tv_sec = -1;
}
#endif
}
// return elapsed time in seconds
elapsed_time elapsed() const
{
typedef elapsed_time::nanosecond_type nanosecond_type;
static const double clock_to_nano_seconds = 1E9 / CLOCKS_PER_SEC;
elapsed_time return_value;
// processor / system time
return_value.system = static_cast<nanosecond_type>(double(std::clock() - _start_time_clock) * clock_to_nano_seconds);
#if defined(BOOST_TEST_TIMER_WINDOWS_API)
static const nanosecond_type tick_per_sec = details::get_tick_freq();
LARGE_INTEGER end_time;
::QueryPerformanceCounter(&end_time);
return_value.wall = static_cast<nanosecond_type>(((end_time.QuadPart - _start_time_wall.QuadPart) * 1E9) / tick_per_sec);
#elif defined(BOOST_TEST_TIMER_MACH_API)
static std::pair<nanosecond_type, nanosecond_type> timebase = details::get_time_base();
nanosecond_type clock = mach_absolute_time() - _start_time_wall;
return_value.wall = static_cast<nanosecond_type>((clock * timebase.first) / timebase.second);
#else
struct timespec end_time;
return_value.wall = 0;
if( ::clock_gettime( CLOCK_MONOTONIC, &end_time ) == 0 )
{
return_value.wall = static_cast<nanosecond_type>((end_time.tv_sec - _start_time_wall.tv_sec) * 1E9 + (end_time.tv_nsec - _start_time_wall.tv_nsec));
}
#endif
return return_value;
}
private:
std::clock_t _start_time_clock;
#if defined(BOOST_TEST_TIMER_WINDOWS_API)
LARGE_INTEGER _start_time_wall;
#elif defined(BOOST_TEST_TIMER_MACH_API)
elapsed_time::nanosecond_type _start_time_wall;
#else
struct timespec _start_time_wall;
#endif
};
//____________________________________________________________________________//
} // namespace timer
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_UTILS_TIMER_HPP

View File

@@ -0,0 +1,162 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : wraps strstream and stringstream (depends with one is present)
// to provide the unified interface
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_WRAP_STRINGSTREAM_HPP
#define BOOST_TEST_UTILS_WRAP_STRINGSTREAM_HPP
// Boost.Test
#include <boost/test/detail/config.hpp>
// STL
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream> // for std::ostrstream
#else
#include <sstream> // for std::ostringstream
#endif // BOOST_NO_STRINGSTREAM
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
// ************************************************************************** //
// ************** basic_wrap_stringstream ************** //
// ************************************************************************** //
template<typename CharT>
class basic_wrap_stringstream {
public:
#if defined(BOOST_CLASSIC_IOSTREAMS)
typedef std::ostringstream wrapped_stream;
#elif defined(BOOST_NO_STRINGSTREAM)
typedef std::basic_ostrstream<CharT> wrapped_stream;
#else
typedef std::basic_ostringstream<CharT> wrapped_stream;
#endif // BOOST_NO_STRINGSTREAM
// Access methods
basic_wrap_stringstream& ref();
wrapped_stream& stream();
std::basic_string<CharT> const& str();
private:
// Data members
wrapped_stream m_stream;
std::basic_string<CharT> m_str;
};
//____________________________________________________________________________//
template <typename CharT, typename T>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, T const& t )
{
targ.stream() << t;
return targ;
}
//____________________________________________________________________________//
template <typename CharT>
inline typename basic_wrap_stringstream<CharT>::wrapped_stream&
basic_wrap_stringstream<CharT>::stream()
{
return m_stream;
}
//____________________________________________________________________________//
template <typename CharT>
inline basic_wrap_stringstream<CharT>&
basic_wrap_stringstream<CharT>::ref()
{
return *this;
}
//____________________________________________________________________________//
template <typename CharT>
inline std::basic_string<CharT> const&
basic_wrap_stringstream<CharT>::str()
{
#ifdef BOOST_NO_STRINGSTREAM
m_str.assign( m_stream.str(), m_stream.pcount() );
m_stream.freeze( false );
#else
m_str = m_stream.str();
#endif
return m_str;
}
//____________________________________________________________________________//
template <typename CharT>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, basic_wrap_stringstream<CharT>& src )
{
targ << src.str();
return targ;
}
//____________________________________________________________________________//
#if BOOST_TEST_USE_STD_LOCALE
template <typename CharT>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, std::ios_base& (BOOST_TEST_CALL_DECL *man)(std::ios_base&) )
{
targ.stream() << man;
return targ;
}
//____________________________________________________________________________//
template<typename CharT,typename Elem,typename Tr>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, std::basic_ostream<Elem,Tr>& (BOOST_TEST_CALL_DECL *man)(std::basic_ostream<Elem, Tr>&) )
{
targ.stream() << man;
return targ;
}
//____________________________________________________________________________//
template<typename CharT,typename Elem,typename Tr>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, std::basic_ios<Elem, Tr>& (BOOST_TEST_CALL_DECL *man)(std::basic_ios<Elem, Tr>&) )
{
targ.stream() << man;
return targ;
}
//____________________________________________________________________________//
#endif
// ************************************************************************** //
// ************** wrap_stringstream ************** //
// ************************************************************************** //
typedef basic_wrap_stringstream<char> wrap_stringstream;
typedef basic_wrap_stringstream<wchar_t> wrap_wstringstream;
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_WRAP_STRINGSTREAM_HPP

View File

@@ -0,0 +1,145 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : common code used by any agent serving as OF_XML printer
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_XML_PRINTER_HPP
#define BOOST_TEST_UTILS_XML_PRINTER_HPP
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/custom_manip.hpp>
#include <boost/test/utils/foreach.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
// Boost
#include <boost/config.hpp>
// STL
#include <iostream>
#include <map>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace utils {
// ************************************************************************** //
// ************** xml print helpers ************** //
// ************************************************************************** //
inline void
print_escaped( std::ostream& where_to, const_string value )
{
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
static std::map<char,char const*> const char_type{{
{'<' , "lt"},
{'>' , "gt"},
{'&' , "amp"},
{'\'', "apos"},
{'"' , "quot"}
}};
#else
static std::map<char,char const*> char_type;
if( char_type.empty() ) {
char_type['<'] = "lt";
char_type['>'] = "gt";
char_type['&'] = "amp";
char_type['\'']= "apos";
char_type['"'] = "quot";
}
#endif
BOOST_TEST_FOREACH( char, c, value ) {
std::map<char,char const*>::const_iterator found_ref = char_type.find( c );
if( found_ref != char_type.end() )
where_to << '&' << found_ref->second << ';';
else
where_to << c;
}
}
//____________________________________________________________________________//
inline void
print_escaped( std::ostream& where_to, std::string const& value )
{
print_escaped( where_to, const_string( value ) );
}
//____________________________________________________________________________//
template<typename T>
inline void
print_escaped( std::ostream& where_to, T const& value )
{
where_to << value;
}
//____________________________________________________________________________//
inline void
print_escaped_cdata( std::ostream& where_to, const_string value )
{
static const_string cdata_end( "]]>" );
const_string::size_type pos = value.find( cdata_end );
if( pos == const_string::npos )
where_to << value;
else {
where_to << value.substr( 0, pos+2 ) << cdata_end
<< BOOST_TEST_L( "<![CDATA[" ) << value.substr( pos+2 );
}
}
//____________________________________________________________________________//
typedef custom_manip<struct attr_value_t> attr_value;
template<typename T>
inline std::ostream&
operator<<( custom_printer<attr_value> const& p, T const& value )
{
*p << "=\"";
print_escaped( *p, value );
*p << '"';
return *p;
}
//____________________________________________________________________________//
typedef custom_manip<struct cdata_t> cdata;
inline std::ostream&
operator<<( custom_printer<cdata> const& p, const_string value )
{
*p << BOOST_TEST_L( "<![CDATA[" );
print_escaped_cdata( *p, value );
return *p << BOOST_TEST_L( "]]>" );
}
//____________________________________________________________________________//
} // namespace utils
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_XML_PRINTER_HPP