]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/test/example/unit_test_example_12.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / test / example / unit_test_example_12.cpp
CommitLineData
7c673cae
FG
1// (C) Copyright Gennadiy Rozental 2001-2014.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5
6// See http://www.boost.org/libs/test for the library home page.
7
8// Boost.Test
9#include <boost/test/unit_test.hpp>
92f5a8d4 10#include <boost/test/utils/algorithm.hpp>
7c673cae
FG
11#include <boost/test/tools/floating_point_comparison.hpp>
12#include <boost/test/parameterized_test.hpp>
13using namespace boost::unit_test;
14
15// BOOST
16#include <boost/functional.hpp>
17#include <boost/static_assert.hpp>
18#include <boost/mem_fn.hpp>
20effc67 19#include <boost/bind/bind.hpp>
7c673cae
FG
20
21// STL
22#include <string>
23#include <stdexcept>
24#include <algorithm>
25#include <functional>
26#include <iostream>
27#include <memory>
28#include <list>
29
30//____________________________________________________________________________//
31
32template<int n>
33struct power_of_10 {
34 BOOST_STATIC_CONSTANT( unsigned long, value = 10*power_of_10<n-1>::value );
35};
36
37template<>
38struct power_of_10<0> {
39 BOOST_STATIC_CONSTANT( unsigned long, value = 1 );
40};
41
42//____________________________________________________________________________//
43
44template<int AlphabetSize>
45class hash_function {
46public:
47 BOOST_STATIC_ASSERT( AlphabetSize <= 5 );
48
49 explicit hash_function( std::string const& alphabet )
50 : m_alphabet( alphabet )
51 {
52 if( m_alphabet.size() != AlphabetSize )
53 throw std::runtime_error( "Wrong alphabet size" );
54
55 std::sort( m_alphabet.begin(), m_alphabet.end() );
56
57 if( std::adjacent_find( m_alphabet.begin(), m_alphabet.end() ) != m_alphabet.end() )
58 throw std::logic_error( "Duplicate characters in alphabet" );
59 }
60
61 unsigned long operator()( std::string const& arg )
62 {
63 m_result = 0;
64
65 if( arg.length() > 8 )
66 throw std::runtime_error( "Wrong argument size" );
67
68 std::string::const_iterator it = std::find_if( arg.begin(), arg.end(),
92f5a8d4 69 BOOST_TEST_BIND1ST( boost::mem_fun( &hash_function::helper_ ), this ) );
7c673cae
FG
70
71 if( it != arg.end() )
72 throw std::out_of_range( std::string( "Invalid character " ) + *it );
73
74 return m_result;
75 }
76
77private:
78 bool helper_( char c )
79 {
80 std::string::const_iterator it = std::find( m_alphabet.begin(), m_alphabet.end(), c );
81
82 if( it == m_alphabet.end() )
83 return true;
84
85 m_result += power_of_10_( it - m_alphabet.begin() );
86
87 return false;
88 }
89
90 unsigned long power_of_10_( int i ) {
91 switch( i ) {
92 case 0: return power_of_10<0>::value;
93 case 1: return power_of_10<1>::value;
94 case 2: return power_of_10<2>::value;
95 case 3: return power_of_10<3>::value;
96 case 4: return power_of_10<4>::value;
97 default: return 0;
98 }
99 }
100
101 // Data members
102 std::string m_alphabet;
103 unsigned long m_result;
104};
105
106//____________________________________________________________________________//
107
108struct hash_function_test_data {
109 std::string orig_string;
110 unsigned long exp_value;
111
112 friend std::istream& operator>>( std::istream& istr, hash_function_test_data& test_data )
113 {
114 std::istream& tmp = istr >> test_data.orig_string;
115 return !tmp ? tmp : istr >> test_data.exp_value;
116 }
117};
118
119//____________________________________________________________________________//
120
121class hash_function_tester {
122public:
123 explicit hash_function_tester( std::string const& alphabet )
124 : m_function_under_test( alphabet ) {}
125
126 void test( hash_function_test_data const& test_data )
127 {
128 if( test_data.exp_value == (unsigned long)-1 )
129 BOOST_CHECK_THROW( m_function_under_test( test_data.orig_string ), std::runtime_error );
130 else if( test_data.exp_value == (unsigned long)-2 )
131 BOOST_CHECK_THROW( m_function_under_test( test_data.orig_string ), std::out_of_range );
132 else {
133 BOOST_TEST_MESSAGE( "Testing: " << test_data.orig_string );
134 BOOST_CHECK_EQUAL( m_function_under_test( test_data.orig_string ), test_data.exp_value );
135 }
136 }
137
138private:
139 hash_function<4> m_function_under_test;
140};
141
142//____________________________________________________________________________//
143
144struct massive_hash_function_test : test_suite {
145 massive_hash_function_test() : test_suite( "massive_hash_function_test" ) {
146 std::string alphabet;
147 std::cout << "Enter alphabet (4 characters without delimeters)\n";
148 std::cin >> alphabet;
149
150 boost::shared_ptr<hash_function_tester> instance( new hash_function_tester( alphabet ) );
151
152 std::cout << "\nEnter test data in a format [string] [value] to check correct calculation\n";
153 std::cout << "Enter test data in a format [string] -1 to check long string validation\n";
154 std::cout << "Enter test data in a format [string] -2 to check invalid argument string validation\n";
155
156 std::list<hash_function_test_data> test_data_store;
157
158 while( !std::cin.eof() ) {
159 hash_function_test_data test_data;
160
161 if( !(std::cin >> test_data) )
162 break;
163
164 test_data_store.push_back( test_data );
165 }
166
167 add( make_test_case( &hash_function_tester::test,
168 "hash_function_tester",
169 __FILE__,
170 __LINE__,
171 instance,
172 test_data_store.begin(),
173 test_data_store.end() ) );
174 }
175};
176
177//____________________________________________________________________________//
178
179test_suite*
180init_unit_test_suite( int, char* [] ) {
181 framework::master_test_suite().p_name.value = "Unit test example 12";
182
183 framework::master_test_suite().add( new massive_hash_function_test );
184
185 return 0;
186}
187
188//____________________________________________________________________________//
189
190// EOF