mirror of
https://github.com/boostorg/utility.git
synced 2025-05-08 18:34:02 +00:00
This commit was generated by cvs2svn to compensate for changes in r4,
which included commits to RCS files with non-trunk default branches. [SVN r7621]
This commit is contained in:
commit
06adfe9658
96
.gitattributes
vendored
Normal file
96
.gitattributes
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
* text=auto !eol svneol=native#text/plain
|
||||
*.gitattributes text svneol=native#text/plain
|
||||
|
||||
# Scriptish formats
|
||||
*.bat text svneol=native#text/plain
|
||||
*.bsh text svneol=native#text/x-beanshell
|
||||
*.cgi text svneol=native#text/plain
|
||||
*.cmd text svneol=native#text/plain
|
||||
*.js text svneol=native#text/javascript
|
||||
*.php text svneol=native#text/x-php
|
||||
*.pl text svneol=native#text/x-perl
|
||||
*.pm text svneol=native#text/x-perl
|
||||
*.py text svneol=native#text/x-python
|
||||
*.sh eol=lf svneol=LF#text/x-sh
|
||||
configure eol=lf svneol=LF#text/x-sh
|
||||
|
||||
# Image formats
|
||||
*.bmp binary svneol=unset#image/bmp
|
||||
*.gif binary svneol=unset#image/gif
|
||||
*.ico binary svneol=unset#image/ico
|
||||
*.jpeg binary svneol=unset#image/jpeg
|
||||
*.jpg binary svneol=unset#image/jpeg
|
||||
*.png binary svneol=unset#image/png
|
||||
*.tif binary svneol=unset#image/tiff
|
||||
*.tiff binary svneol=unset#image/tiff
|
||||
*.svg text svneol=native#image/svg%2Bxml
|
||||
|
||||
# Data formats
|
||||
*.pdf binary svneol=unset#application/pdf
|
||||
*.avi binary svneol=unset#video/avi
|
||||
*.doc binary svneol=unset#application/msword
|
||||
*.dsp text svneol=crlf#text/plain
|
||||
*.dsw text svneol=crlf#text/plain
|
||||
*.eps binary svneol=unset#application/postscript
|
||||
*.gz binary svneol=unset#application/gzip
|
||||
*.mov binary svneol=unset#video/quicktime
|
||||
*.mp3 binary svneol=unset#audio/mpeg
|
||||
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
|
||||
*.ps binary svneol=unset#application/postscript
|
||||
*.psd binary svneol=unset#application/photoshop
|
||||
*.rdf binary svneol=unset#text/rdf
|
||||
*.rss text svneol=unset#text/xml
|
||||
*.rtf binary svneol=unset#text/rtf
|
||||
*.sln text svneol=native#text/plain
|
||||
*.swf binary svneol=unset#application/x-shockwave-flash
|
||||
*.tgz binary svneol=unset#application/gzip
|
||||
*.vcproj text svneol=native#text/xml
|
||||
*.vcxproj text svneol=native#text/xml
|
||||
*.vsprops text svneol=native#text/xml
|
||||
*.wav binary svneol=unset#audio/wav
|
||||
*.xls binary svneol=unset#application/vnd.ms-excel
|
||||
*.zip binary svneol=unset#application/zip
|
||||
|
||||
# Text formats
|
||||
.htaccess text svneol=native#text/plain
|
||||
*.bbk text svneol=native#text/xml
|
||||
*.cmake text svneol=native#text/plain
|
||||
*.css text svneol=native#text/css
|
||||
*.dtd text svneol=native#text/xml
|
||||
*.htm text svneol=native#text/html
|
||||
*.html text svneol=native#text/html
|
||||
*.ini text svneol=native#text/plain
|
||||
*.log text svneol=native#text/plain
|
||||
*.mak text svneol=native#text/plain
|
||||
*.qbk text svneol=native#text/plain
|
||||
*.rst text svneol=native#text/plain
|
||||
*.sql text svneol=native#text/x-sql
|
||||
*.txt text svneol=native#text/plain
|
||||
*.xhtml text svneol=native#text/xhtml%2Bxml
|
||||
*.xml text svneol=native#text/xml
|
||||
*.xsd text svneol=native#text/xml
|
||||
*.xsl text svneol=native#text/xml
|
||||
*.xslt text svneol=native#text/xml
|
||||
*.xul text svneol=native#text/xul
|
||||
*.yml text svneol=native#text/plain
|
||||
boost-no-inspect text svneol=native#text/plain
|
||||
CHANGES text svneol=native#text/plain
|
||||
COPYING text svneol=native#text/plain
|
||||
INSTALL text svneol=native#text/plain
|
||||
Jamfile text svneol=native#text/plain
|
||||
Jamroot text svneol=native#text/plain
|
||||
Jamfile.v2 text svneol=native#text/plain
|
||||
Jamrules text svneol=native#text/plain
|
||||
Makefile* text svneol=native#text/plain
|
||||
README text svneol=native#text/plain
|
||||
TODO text svneol=native#text/plain
|
||||
|
||||
# Code formats
|
||||
*.c text svneol=native#text/plain
|
||||
*.cpp text svneol=native#text/plain
|
||||
*.h text svneol=native#text/plain
|
||||
*.hpp text svneol=native#text/plain
|
||||
*.ipp text svneol=native#text/plain
|
||||
*.tpp text svneol=native#text/plain
|
||||
*.jam text svneol=native#text/plain
|
||||
*.java text svneol=native#text/plain
|
406
algo_opt_examples.cpp
Normal file
406
algo_opt_examples.cpp
Normal file
@ -0,0 +1,406 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1999
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* This file provides some example of type_traits usage -
|
||||
* by "optimising" various algorithms:
|
||||
*
|
||||
* opt::copy - optimised for trivial copy (cf std::copy)
|
||||
* opt::fill - optimised for trivial copy/small types (cf std::fill)
|
||||
* opt::destroy_array - an example of optimisation based upon omitted destructor calls
|
||||
* opt::iter_swap - uses type_traits to determine whether the iterator is a proxy
|
||||
* in which case it uses a "safe" approach, otherwise calls swap
|
||||
* on the assumption that swap may be specialised for the pointed-to type.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::cin;
|
||||
|
||||
namespace opt{
|
||||
|
||||
//
|
||||
// algorithm destroy_arry:
|
||||
// The reverse of std::unitialized_copy, takes a block of
|
||||
// unitialized memory and calls destructors on all objects therein.
|
||||
//
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <bool>
|
||||
struct array_destroyer
|
||||
{
|
||||
template <class T>
|
||||
static void destroy_array(T* i, T* j){ do_destroy_array(i, j); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct array_destroyer<true>
|
||||
{
|
||||
template <class T>
|
||||
static void destroy_array(T*, T*){}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void do_destroy_array(T* first, T* last)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
first->~T();
|
||||
++first;
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace detail
|
||||
|
||||
template <class T>
|
||||
inline void destroy_array(T* p1, T* p2)
|
||||
{
|
||||
detail::array_destroyer<boost::has_trivial_destructor<T>::value>::destroy_array(p1, p2);
|
||||
}
|
||||
|
||||
//
|
||||
// unoptimised versions of destroy_array:
|
||||
//
|
||||
template <class T>
|
||||
void destroy_array1(T* first, T* last)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
first->~T();
|
||||
++first;
|
||||
}
|
||||
}
|
||||
template <class T>
|
||||
void destroy_array2(T* first, T* last)
|
||||
{
|
||||
for(; first != last; ++first) first->~T();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// opt::copy
|
||||
// same semantics as std::copy
|
||||
// calls memcpy where appropiate.
|
||||
//
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <bool b>
|
||||
struct copier
|
||||
{
|
||||
template<typename I1, typename I2>
|
||||
static I2 do_copy(I1 first, I1 last, I2 out);
|
||||
};
|
||||
|
||||
template <bool b>
|
||||
template<typename I1, typename I2>
|
||||
I2 copier<b>::do_copy(I1 first, I1 last, I2 out)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
*out = *first;
|
||||
++out;
|
||||
++first;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
template <>
|
||||
struct copier<true>
|
||||
{
|
||||
template<typename I1, typename I2>
|
||||
static I2* do_copy(I1* first, I1* last, I2* out)
|
||||
{
|
||||
memcpy(out, first, (last-first)*sizeof(I2));
|
||||
return out+(last-first);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
template<typename I1, typename I2>
|
||||
inline I2 copy(I1 first, I1 last, I2 out)
|
||||
{
|
||||
typedef typename boost::remove_cv<typename std::iterator_traits<I1>::value_type>::type v1_t;
|
||||
typedef typename boost::remove_cv<typename std::iterator_traits<I2>::value_type>::type v2_t;
|
||||
enum{ can_opt = boost::is_same<v1_t, v2_t>::value
|
||||
&& boost::is_pointer<I1>::value
|
||||
&& boost::is_pointer<I2>::value
|
||||
&& boost::has_trivial_assign<v1_t>::value };
|
||||
return detail::copier<can_opt>::do_copy(first, last, out);
|
||||
}
|
||||
|
||||
//
|
||||
// fill
|
||||
// same as std::fill, uses memset where appropriate, along with call_traits
|
||||
// to "optimise" parameter passing.
|
||||
//
|
||||
namespace detail{
|
||||
|
||||
template <bool opt>
|
||||
struct filler
|
||||
{
|
||||
template <typename I, typename T>
|
||||
static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val);
|
||||
};
|
||||
|
||||
template <bool b>
|
||||
template <typename I, typename T>
|
||||
void filler<b>::do_fill(I first, I last, typename boost::call_traits<T>::param_type val)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
*first = val;
|
||||
++first;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
struct filler<true>
|
||||
{
|
||||
template <typename I, typename T>
|
||||
static void do_fill(I first, I last, T val)
|
||||
{
|
||||
memset(first, val, last-first);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class I, class T>
|
||||
inline void fill(I first, I last, const T& val)
|
||||
{
|
||||
enum{ can_opt = boost::is_pointer<I>::value
|
||||
&& boost::is_arithmetic<T>::value
|
||||
&& (sizeof(T) == 1) };
|
||||
typedef detail::filler<can_opt> filler_t;
|
||||
filler_t::template do_fill<I,T>(first, last, val);
|
||||
}
|
||||
|
||||
//
|
||||
// iter_swap:
|
||||
// tests whether iterator is a proxying iterator or not, and
|
||||
// uses optimal form accordingly:
|
||||
//
|
||||
namespace detail{
|
||||
|
||||
template <bool b>
|
||||
struct swapper
|
||||
{
|
||||
template <typename I>
|
||||
static void do_swap(I one, I two)
|
||||
{
|
||||
typedef typename std::iterator_traits<I>::value_type v_t;
|
||||
v_t v = *one;
|
||||
*one = *two;
|
||||
*two = v;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct swapper<true>
|
||||
{
|
||||
template <typename I>
|
||||
static void do_swap(I one, I two)
|
||||
{
|
||||
using std::swap;
|
||||
swap(*one, *two);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename I1, typename I2>
|
||||
inline void iter_swap(I1 one, I2 two)
|
||||
{
|
||||
typedef typename std::iterator_traits<I1>::reference r1_t;
|
||||
typedef typename std::iterator_traits<I2>::reference r2_t;
|
||||
enum{ can_opt = boost::is_reference<r1_t>::value && boost::is_reference<r2_t>::value && boost::is_same<r1_t, r2_t>::value };
|
||||
detail::swapper<can_opt>::do_swap(one, two);
|
||||
}
|
||||
|
||||
|
||||
}; // namespace opt
|
||||
|
||||
//
|
||||
// define some global data:
|
||||
//
|
||||
const int array_size = 1000;
|
||||
int i_array[array_size] = {0,};
|
||||
const int ci_array[array_size] = {0,};
|
||||
char c_array[array_size] = {0,};
|
||||
const char cc_array[array_size] = { 0,};
|
||||
|
||||
const int iter_count = 1000000;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
//
|
||||
// test destroy_array,
|
||||
// compare destruction time of an array of ints
|
||||
// with unoptimised form.
|
||||
//
|
||||
cout << "Measuring times in micro-seconds per 1000 elements processed" << endl << endl;
|
||||
cout << "testing destroy_array...\n"
|
||||
"[Some compilers may be able to optimise the \"unoptimised\"\n versions as well as type_traits does.]" << endl;
|
||||
/*cache load*/ opt::destroy_array(i_array, i_array + array_size);
|
||||
boost::timer t;
|
||||
double result;
|
||||
int i;
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::destroy_array(i_array, i_array + array_size);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "destroy_array<int>: " << result << endl;
|
||||
/*cache load*/ opt::destroy_array1(i_array, i_array + array_size);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::destroy_array1(i_array, i_array + array_size);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "destroy_array<int>(unoptimised#1): " << result << endl;
|
||||
/*cache load*/ opt::destroy_array2(i_array, i_array + array_size);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::destroy_array2(i_array, i_array + array_size);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "destroy_array<int>(unoptimised#2): " << result << endl << endl;
|
||||
|
||||
cout << "testing copy...\n"
|
||||
"[Some standard library versions may already perform this optimisation.]" << endl;
|
||||
/*cache load*/ opt::copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "opt::copy<const int*, int*>: " << result << endl;
|
||||
/*cache load*/ std::copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
std::copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "std::copy<const int*, int*>: " << result << endl;
|
||||
/*cache load*/ opt::detail::copier<false>::template do_copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::detail::copier<false>::template do_copy<const int*, int*>(ci_array, ci_array + array_size, i_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "standard \"unoptimised\" copy: " << result << endl << endl;
|
||||
|
||||
/*cache load*/ opt::copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "opt::copy<const char*, char*>: " << result << endl;
|
||||
/*cache load*/ std::copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
std::copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "std::copy<const char*, char*>: " << result << endl;
|
||||
/*cache load*/ opt::detail::copier<false>::template do_copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::detail::copier<false>::template do_copy<const char*, char*>(cc_array, cc_array + array_size, c_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "standard \"unoptimised\" copy: " << result << endl << endl;
|
||||
|
||||
cout << "testing fill(char)...\n"
|
||||
"[Some standard library versions may already perform this optimisation.]" << endl;
|
||||
/*cache load*/ opt::fill<char*, char>(c_array, c_array + array_size, (char)3);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::fill<char*, char>(c_array, c_array + array_size, (char)3);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "opt::fill<char*, char>: " << result << endl;
|
||||
/*cache load*/ std::fill(c_array, c_array + array_size, (char)3);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
std::fill(c_array, c_array + array_size, (char)3);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "std::fill<char*, char>: " << result << endl << endl;
|
||||
|
||||
cout << "testing fill(int)...\n"
|
||||
"[Tests the effect of call_traits pass-by-value optimisation -\nthe value of this optimisation may depend upon hardware characteristics.]" << endl;
|
||||
/*cache load*/ opt::fill<int*, int>(i_array, i_array + array_size, 3);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::fill<int*, int>(i_array, i_array + array_size, 3);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "opt::fill<int*, int>: " << result << endl;
|
||||
/*cache load*/ std::fill(i_array, i_array + array_size, 3);
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
std::fill(i_array, i_array + array_size, 3);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "std::fill<int*, int>: " << result << endl << endl;
|
||||
|
||||
//
|
||||
// testing iter_swap
|
||||
// really just a check that it does in fact compile...
|
||||
std::vector<int> v1;
|
||||
v1.push_back(0);
|
||||
v1.push_back(1);
|
||||
std::vector<bool> v2;
|
||||
v2.push_back(0);
|
||||
v2.push_back(1);
|
||||
opt::iter_swap(v1.begin(), v1.begin()+1);
|
||||
opt::iter_swap(v2.begin(), v2.begin()+1);
|
||||
|
||||
cout << "Press any key to exit...";
|
||||
cin.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
208
call_traits_test.cpp
Normal file
208
call_traits_test.cpp
Normal file
@ -0,0 +1,208 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <typeinfo>
|
||||
#include <boost/call_traits.hpp>
|
||||
|
||||
//
|
||||
// struct contained models a type that contains a type (for example std::pair)
|
||||
// arrays are contained by value, and have to be treated as a special case:
|
||||
//
|
||||
template <class T>
|
||||
struct contained
|
||||
{
|
||||
// define our typedefs first, arrays are stored by value
|
||||
// so value_type is not the same as result_type:
|
||||
typedef typename boost::call_traits<T>::param_type param_type;
|
||||
typedef typename boost::call_traits<T>::reference reference;
|
||||
typedef typename boost::call_traits<T>::const_reference const_reference;
|
||||
typedef T value_type;
|
||||
typedef typename boost::call_traits<T>::value_type result_type;
|
||||
|
||||
// stored value:
|
||||
value_type v_;
|
||||
|
||||
// constructors:
|
||||
contained() {}
|
||||
contained(param_type p) : v_(p){}
|
||||
// return byval:
|
||||
result_type value() { return v_; }
|
||||
// return by_ref:
|
||||
reference get() { return v_; }
|
||||
const_reference const_get()const { return v_; }
|
||||
// pass value:
|
||||
void call(param_type p){}
|
||||
|
||||
};
|
||||
|
||||
template <class T, std::size_t N>
|
||||
struct contained<T[N]>
|
||||
{
|
||||
typedef typename boost::call_traits<T[N]>::param_type param_type;
|
||||
typedef typename boost::call_traits<T[N]>::reference reference;
|
||||
typedef typename boost::call_traits<T[N]>::const_reference const_reference;
|
||||
typedef T value_type[N];
|
||||
typedef typename boost::call_traits<T[N]>::value_type result_type;
|
||||
|
||||
value_type v_;
|
||||
|
||||
contained(param_type p)
|
||||
{
|
||||
std::copy(p, p+N, v_);
|
||||
}
|
||||
// return byval:
|
||||
result_type value() { return v_; }
|
||||
// return by_ref:
|
||||
reference get() { return v_; }
|
||||
const_reference const_get()const { return v_; }
|
||||
void call(param_type p){}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
contained<typename boost::call_traits<T>::value_type> wrap(const T& t)
|
||||
{
|
||||
return contained<typename boost::call_traits<T>::value_type>(t);
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
std::pair<
|
||||
typename boost::call_traits<T1>::value_type,
|
||||
typename boost::call_traits<T2>::value_type>
|
||||
make_pair(const T1& t1, const T2& t2)
|
||||
{
|
||||
return std::pair<
|
||||
typename boost::call_traits<T1>::value_type,
|
||||
typename boost::call_traits<T2>::value_type>(t1, t2);
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
//
|
||||
// struct checker:
|
||||
// verifies behaviour of contained example:
|
||||
//
|
||||
template <class T>
|
||||
struct checker
|
||||
{
|
||||
typedef typename boost::call_traits<T>::param_type param_type;
|
||||
void operator()(param_type);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void checker<T>::operator()(param_type p)
|
||||
{
|
||||
T t(p);
|
||||
contained<T> c(t);
|
||||
cout << "checking contained<" << typeid(T).name() << ">..." << endl;
|
||||
assert(t == c.value());
|
||||
assert(t == c.get());
|
||||
assert(t == c.const_get());
|
||||
|
||||
cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained<T>::value).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained<T>::get).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained<T>::const_get).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T).name() << ">::call() is: " << typeid(&contained<T>::call).name() << endl;
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
template <class T, std::size_t N>
|
||||
struct checker<T[N]>
|
||||
{
|
||||
typedef typename boost::call_traits<T[N]>::param_type param_type;
|
||||
void operator()(param_type);
|
||||
};
|
||||
|
||||
template <class T, std::size_t N>
|
||||
void checker<T[N]>::operator()(param_type t)
|
||||
{
|
||||
contained<T[N]> c(t);
|
||||
cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl;
|
||||
unsigned int i = 0;
|
||||
for(i = 0; i < N; ++i)
|
||||
assert(t[i] == c.value()[i]);
|
||||
for(i = 0; i < N; ++i)
|
||||
assert(t[i] == c.get()[i]);
|
||||
for(i = 0; i < N; ++i)
|
||||
assert(t[i] == c.const_get()[i]);
|
||||
|
||||
cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained<T[N]>::v_).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained<T[N]>::value).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained<T[N]>::get).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained<T[N]>::const_get).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained<T[N]>::call).name() << endl;
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
//
|
||||
// check_wrap:
|
||||
// verifies behaviour of "wrap":
|
||||
//
|
||||
template <class T, class U, class V>
|
||||
void check_wrap(T c, U u, const V& v)
|
||||
{
|
||||
cout << "checking contained<" << typeid(T::value_type).name() << ">..." << endl;
|
||||
assert(c.get() == u);
|
||||
cout << "typeof deduced argument was: " << typeid(V).name() << endl;
|
||||
cout << "typeof deduced parameter after adjustment was: " << typeid(v).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T::value_type).name() << ">::v_ is: " << typeid(&T::v_).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T::value_type).name() << ">::value is: " << typeid(&T::value).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T::value_type).name() << ">::get is: " << typeid(&T::get).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T::value_type).name() << ">::const_get is: " << typeid(&T::const_get).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T::value_type).name() << ">::call is: " << typeid(&T::call).name() << endl;
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
//
|
||||
// check_make_pair:
|
||||
// verifies behaviour of "make_pair":
|
||||
//
|
||||
template <class T, class U, class V>
|
||||
void check_make_pair(T c, U u, V v)
|
||||
{
|
||||
cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl;
|
||||
assert(c.first == u);
|
||||
assert(c.second == v);
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
|
||||
struct UDT
|
||||
{
|
||||
int i_;
|
||||
UDT() : i_(2){}
|
||||
bool operator == (const UDT& v){ return v.i_ == i_; }
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
checker<UDT> c1;
|
||||
UDT u;
|
||||
c1(u);
|
||||
checker<int> c2;
|
||||
int i = 2;
|
||||
c2(i);
|
||||
int* pi = &i;
|
||||
checker<int*> c3;
|
||||
c3(pi);
|
||||
checker<int&> c4;
|
||||
c4(i);
|
||||
checker<const int&> c5;
|
||||
c5(i);
|
||||
|
||||
int a[2] = {1,2};
|
||||
checker<int[2]> c6;
|
||||
c6(a);
|
||||
|
||||
check_wrap(wrap(2), 2, 2);
|
||||
const char ca[4] = "abc";
|
||||
// compiler can't deduce this for some reason:
|
||||
//check_wrap(wrap(ca), ca, ca);
|
||||
check_wrap(wrap(a), a, a);
|
||||
check_make_pair(::make_pair(a, a), a, a);
|
||||
|
||||
return 0;
|
||||
}
|
149
cast_test.cpp
Normal file
149
cast_test.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
// boost utility cast test program -----------------------------------------//
|
||||
|
||||
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
|
||||
// and distribute this software is granted provided this copyright
|
||||
// notice appears in all copies. This software is provided "as is" without
|
||||
// express or implied warranty, and with no claim as to its suitability for
|
||||
// any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 28 Jun 00 implicit_cast removed (Beman Dawes)
|
||||
// 30 Aug 99 value_cast replaced by numeric_cast
|
||||
// 3 Aug 99 Initial Version
|
||||
|
||||
#include <iostream>
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
#include <boost/cast.hpp>
|
||||
|
||||
# if SCHAR_MAX == LONG_MAX
|
||||
# error "This test program doesn't work if SCHAR_MAX == LONG_MAX"
|
||||
# endif
|
||||
|
||||
using namespace boost;
|
||||
using std::cout;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Base
|
||||
{
|
||||
virtual char kind() { return 'B'; }
|
||||
};
|
||||
|
||||
struct Base2
|
||||
{
|
||||
virtual char kind2() { return '2'; }
|
||||
};
|
||||
|
||||
struct Derived : public Base, Base2
|
||||
{
|
||||
virtual char kind() { return 'D'; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
cout << "Usage: test_casts [n], where n omitted or is:\n"
|
||||
" 1 = execute #1 assert failure (#ifndef NDEBUG)\n"
|
||||
" 2 = execute #2 assert failure (#ifndef NDEBUG)\n"
|
||||
"Example: test_casts 2\n\n";
|
||||
|
||||
# ifdef NDEBUG
|
||||
cout << "NDEBUG is defined\n";
|
||||
# else
|
||||
cout << "NDEBUG is not defined\n";
|
||||
# endif
|
||||
|
||||
cout << "\nBeginning tests...\n";
|
||||
|
||||
// test polymorphic_cast ---------------------------------------------------//
|
||||
|
||||
// tests which should succeed
|
||||
Base * base = new Derived;
|
||||
Base2 * base2 = 0;
|
||||
Derived * derived = 0;
|
||||
derived = polymorphic_downcast<Derived*>( base ); // downcast
|
||||
assert( derived->kind() == 'D' );
|
||||
|
||||
derived = 0;
|
||||
derived = polymorphic_cast<Derived*>( base ); // downcast, throw on error
|
||||
assert( derived->kind() == 'D' );
|
||||
|
||||
base2 = polymorphic_cast<Base2*>( base ); // crosscast
|
||||
assert( base2->kind2() == '2' );
|
||||
|
||||
// tests which should result in errors being detected
|
||||
int err_count = 0;
|
||||
base = new Base;
|
||||
|
||||
if ( argc > 1 && *argv[1] == '1' )
|
||||
{ derived = polymorphic_downcast<Derived*>( base ); } // #1 assert failure
|
||||
|
||||
bool caught_exception = false;
|
||||
try { derived = polymorphic_cast<Derived*>( base ); }
|
||||
catch (std::bad_cast)
|
||||
{ cout<<"caught bad_cast\n"; caught_exception = true; }
|
||||
if ( !caught_exception ) ++err_count;
|
||||
// the following is just so generated code can be inspected
|
||||
if ( derived->kind() == 'B' ) ++err_count;
|
||||
|
||||
// test implicit_cast and numeric_cast -------------------------------------//
|
||||
|
||||
// tests which should succeed
|
||||
long small_value = 1;
|
||||
long small_negative_value = -1;
|
||||
long large_value = std::numeric_limits<long>::max();
|
||||
long large_negative_value = std::numeric_limits<long>::min();
|
||||
signed char c = 0;
|
||||
|
||||
c = large_value; // see if compiler generates warning
|
||||
|
||||
c = numeric_cast<signed char>( small_value );
|
||||
assert( c == 1 );
|
||||
c = 0;
|
||||
c = numeric_cast<signed char>( small_value );
|
||||
assert( c == 1 );
|
||||
c = 0;
|
||||
c = numeric_cast<signed char>( small_negative_value );
|
||||
assert( c == -1 );
|
||||
|
||||
// tests which should result in errors being detected
|
||||
|
||||
caught_exception = false;
|
||||
try { c = numeric_cast<signed char>( large_value ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #1\n"; caught_exception = true; }
|
||||
if ( !caught_exception ) ++err_count;
|
||||
|
||||
caught_exception = false;
|
||||
try { c = numeric_cast<signed char>( large_negative_value ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #2\n"; caught_exception = true; }
|
||||
if ( !caught_exception ) ++err_count;
|
||||
|
||||
unsigned long ul;
|
||||
caught_exception = false;
|
||||
try { ul = numeric_cast<unsigned long>( large_negative_value ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #3\n"; caught_exception = true; }
|
||||
if ( !caught_exception ) ++err_count;
|
||||
|
||||
caught_exception = false;
|
||||
try { ul = numeric_cast<unsigned long>( small_negative_value ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #4\n"; caught_exception = true; }
|
||||
if ( !caught_exception ) ++err_count;
|
||||
|
||||
caught_exception = false;
|
||||
try { numeric_cast<int>( std::numeric_limits<double>::max() ); }
|
||||
catch (bad_numeric_cast)
|
||||
{ cout<<"caught bad_numeric_cast #5\n"; caught_exception = true; }
|
||||
if ( !caught_exception ) ++err_count;
|
||||
|
||||
cout << err_count << " errors detected\nTest "
|
||||
<< (err_count==0 ? "passed\n" : "failed\n");
|
||||
return err_count;
|
||||
} // main
|
23
include/boost/call_traits.hpp
Normal file
23
include/boost/call_traits.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
// (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
// See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp
|
||||
// for full copyright notices.
|
||||
|
||||
#ifndef BOOST_CALL_TRAITS_HPP
|
||||
#define BOOST_CALL_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
#include <boost/detail/ob_call_traits.hpp>
|
||||
#else
|
||||
#include <boost/detail/call_traits.hpp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_CALL_TRAITS_HPP
|
23
include/boost/compressed_pair.hpp
Normal file
23
include/boost/compressed_pair.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
// (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
// See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp
|
||||
// for full copyright notices.
|
||||
|
||||
#ifndef BOOST_COMPRESSED_PAIR_HPP
|
||||
#define BOOST_COMPRESSED_PAIR_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
#include <boost/detail/ob_compressed_pair.hpp>
|
||||
#else
|
||||
#include <boost/detail/compressed_pair.hpp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_COMPRESSED_PAIR_HPP
|
97
include/boost/detail/call_traits.hpp
Normal file
97
include/boost/detail/call_traits.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
#ifndef BOOST_DETAIL_CALL_TRAITS_HPP
|
||||
#define BOOST_DETAIL_CALL_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <typename T, bool isp, bool b1, bool b2>
|
||||
struct ct_imp
|
||||
{
|
||||
typedef const T& param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool isp>
|
||||
struct ct_imp<T, isp, true, true>
|
||||
{
|
||||
typedef T const param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool b1, bool b2>
|
||||
struct ct_imp<T, true, b1, b2>
|
||||
{
|
||||
typedef T const param_type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct call_traits
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
//
|
||||
// C++ Builder workaround: we should be able to define a compile time
|
||||
// constant and pass that as a single template parameter to ct_imp<T,bool>,
|
||||
// however compiler bugs prevent this - instead pass three bool's to
|
||||
// ct_imp<T,bool,bool,bool> and add an extra partial specialisation
|
||||
// of ct_imp to handle the logic. (JM)
|
||||
typedef typename detail::ct_imp<T, ::boost::is_pointer<typename remove_const<T>::type>::value, ::boost::is_arithmetic<typename remove_const<T>::type>::value, sizeof(T) <= sizeof(void*)>::param_type param_type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct call_traits<T&>
|
||||
{
|
||||
typedef T& value_type;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T& param_type; // hh removed const
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct call_traits<T [N]>
|
||||
{
|
||||
private:
|
||||
typedef T array_type[N];
|
||||
public:
|
||||
// degrades array to pointer:
|
||||
typedef const T* value_type;
|
||||
typedef array_type& reference;
|
||||
typedef const array_type& const_reference;
|
||||
typedef const T* param_type;
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct call_traits<const T [N]>
|
||||
{
|
||||
private:
|
||||
typedef const T array_type[N];
|
||||
public:
|
||||
// degrades array to pointer:
|
||||
typedef const T* value_type;
|
||||
typedef array_type& reference;
|
||||
typedef const array_type& const_reference;
|
||||
typedef const T* param_type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_DETAIL_CALL_TRAITS_HPP
|
420
include/boost/detail/compressed_pair.hpp
Normal file
420
include/boost/detail/compressed_pair.hpp
Normal file
@ -0,0 +1,420 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
//
|
||||
// JM changes 25 Jan 2000:
|
||||
// Removed default arguments from compressed_pair_switch to get
|
||||
// C++ Builder 4 to accept them
|
||||
// rewriten swap to get gcc and C++ builder to compile.
|
||||
// added partial specialisations for case T1 == T2 to avoid duplicate constructor defs.
|
||||
|
||||
#ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||
#define BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#ifndef BOOST_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_CALL_TRAITS_HPP
|
||||
#include <boost/call_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// compressed_pair
|
||||
|
||||
namespace details
|
||||
{
|
||||
// JM altered 26 Jan 2000:
|
||||
template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
|
||||
struct compressed_pair_switch;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct compressed_pair_switch<T1, T2, false, false, false>
|
||||
{static const int value = 0;};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct compressed_pair_switch<T1, T2, false, true, true>
|
||||
{static const int value = 3;};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct compressed_pair_switch<T1, T2, false, true, false>
|
||||
{static const int value = 1;};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct compressed_pair_switch<T1, T2, false, false, true>
|
||||
{static const int value = 2;};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct compressed_pair_switch<T1, T2, true, true, true>
|
||||
{static const int value = 4;};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct compressed_pair_switch<T1, T2, true, false, false>
|
||||
{static const int value = 5;};
|
||||
|
||||
template <class T1, class T2, int Version> class compressed_pair_imp;
|
||||
|
||||
#ifdef __GNUC__
|
||||
// workaround for GCC (JM):
|
||||
using std::swap;
|
||||
#endif
|
||||
//
|
||||
// can't call unqualified swap from within classname::swap
|
||||
// as Koenig lookup rules will find only the classname::swap
|
||||
// member function not the global declaration, so use cp_swap
|
||||
// as a forwarding function (JM):
|
||||
template <typename T>
|
||||
inline void cp_swap(T& t1, T& t2)
|
||||
{
|
||||
using std::swap;
|
||||
swap(t1, t2);
|
||||
}
|
||||
|
||||
// 0 derive from neither
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 0>
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||
typedef typename call_traits<first_type>::reference first_reference;
|
||||
typedef typename call_traits<second_type>::reference second_reference;
|
||||
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||
: first_(x), second_(y) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_(x) {}
|
||||
|
||||
explicit compressed_pair_imp(second_param_type y)
|
||||
: second_(y) {}
|
||||
|
||||
first_reference first() {return first_;}
|
||||
first_const_reference first() const {return first_;}
|
||||
|
||||
second_reference second() {return second_;}
|
||||
second_const_reference second() const {return second_;}
|
||||
|
||||
void swap(compressed_pair_imp& y)
|
||||
{
|
||||
cp_swap(first_, y.first_);
|
||||
cp_swap(second_, y.second_);
|
||||
}
|
||||
private:
|
||||
first_type first_;
|
||||
second_type second_;
|
||||
};
|
||||
|
||||
// 1 derive from T1
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 1>
|
||||
: private T1
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||
typedef typename call_traits<first_type>::reference first_reference;
|
||||
typedef typename call_traits<second_type>::reference second_reference;
|
||||
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||
: first_type(x), second_(y) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_type(x) {}
|
||||
|
||||
explicit compressed_pair_imp(second_param_type y)
|
||||
: second_(y) {}
|
||||
|
||||
first_reference first() {return *this;}
|
||||
first_const_reference first() const {return *this;}
|
||||
|
||||
second_reference second() {return second_;}
|
||||
second_const_reference second() const {return second_;}
|
||||
|
||||
void swap(compressed_pair_imp& y)
|
||||
{
|
||||
// no need to swap empty base class:
|
||||
cp_swap(second_, y.second_);
|
||||
}
|
||||
private:
|
||||
second_type second_;
|
||||
};
|
||||
|
||||
// 2 derive from T2
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 2>
|
||||
: private T2
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||
typedef typename call_traits<first_type>::reference first_reference;
|
||||
typedef typename call_traits<second_type>::reference second_reference;
|
||||
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||
: second_type(y), first_(x) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_(x) {}
|
||||
|
||||
explicit compressed_pair_imp(second_param_type y)
|
||||
: second_type(y) {}
|
||||
|
||||
first_reference first() {return first_;}
|
||||
first_const_reference first() const {return first_;}
|
||||
|
||||
second_reference second() {return *this;}
|
||||
second_const_reference second() const {return *this;}
|
||||
|
||||
void swap(compressed_pair_imp& y)
|
||||
{
|
||||
// no need to swap empty base class:
|
||||
cp_swap(first_, y.first_);
|
||||
}
|
||||
|
||||
private:
|
||||
first_type first_;
|
||||
};
|
||||
|
||||
// 3 derive from T1 and T2
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 3>
|
||||
: private T1,
|
||||
private T2
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||
typedef typename call_traits<first_type>::reference first_reference;
|
||||
typedef typename call_traits<second_type>::reference second_reference;
|
||||
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||
: first_type(x), second_type(y) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_type(x) {}
|
||||
|
||||
explicit compressed_pair_imp(second_param_type y)
|
||||
: second_type(y) {}
|
||||
|
||||
first_reference first() {return *this;}
|
||||
first_const_reference first() const {return *this;}
|
||||
|
||||
second_reference second() {return *this;}
|
||||
second_const_reference second() const {return *this;}
|
||||
//
|
||||
// no need to swap empty bases:
|
||||
void swap(compressed_pair_imp&) {}
|
||||
};
|
||||
|
||||
// JM
|
||||
// 4 T1 == T2, T1 and T2 both empty
|
||||
// Note does not actually store an instance of T2 at all -
|
||||
// but reuses T1 base class for both first() and second().
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 4>
|
||||
: private T1
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||
typedef typename call_traits<first_type>::reference first_reference;
|
||||
typedef typename call_traits<second_type>::reference second_reference;
|
||||
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type)
|
||||
: first_type(x) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_type(x) {}
|
||||
|
||||
first_reference first() {return *this;}
|
||||
first_const_reference first() const {return *this;}
|
||||
|
||||
second_reference second() {return *this;}
|
||||
second_const_reference second() const {return *this;}
|
||||
|
||||
void swap(compressed_pair_imp&) {}
|
||||
private:
|
||||
};
|
||||
|
||||
// 5 T1 == T2 and are not empty: //JM
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 5>
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||
typedef typename call_traits<first_type>::reference first_reference;
|
||||
typedef typename call_traits<second_type>::reference second_reference;
|
||||
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||
: first_(x), second_(y) {}
|
||||
|
||||
explicit compressed_pair_imp(first_param_type x)
|
||||
: first_(x), second_(x) {}
|
||||
|
||||
first_reference first() {return first_;}
|
||||
first_const_reference first() const {return first_;}
|
||||
|
||||
second_reference second() {return second_;}
|
||||
second_const_reference second() const {return second_;}
|
||||
|
||||
void swap(compressed_pair_imp<T1, T2, 5>& y)
|
||||
{
|
||||
cp_swap(first_, y.first_);
|
||||
cp_swap(second_, y.second_);
|
||||
}
|
||||
private:
|
||||
first_type first_;
|
||||
second_type second_;
|
||||
};
|
||||
|
||||
} // details
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair
|
||||
: private ::boost::details::compressed_pair_imp<T1, T2,
|
||||
::boost::details::compressed_pair_switch<
|
||||
T1,
|
||||
T2,
|
||||
::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
|
||||
::boost::is_empty<T1>::value,
|
||||
::boost::is_empty<T2>::value>::value>
|
||||
{
|
||||
private:
|
||||
typedef details::compressed_pair_imp<T1, T2,
|
||||
::boost::details::compressed_pair_switch<
|
||||
T1,
|
||||
T2,
|
||||
::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
|
||||
::boost::is_empty<T1>::value,
|
||||
::boost::is_empty<T2>::value>::value> base;
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||
typedef typename call_traits<first_type>::reference first_reference;
|
||||
typedef typename call_traits<second_type>::reference second_reference;
|
||||
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair() : base() {}
|
||||
compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
|
||||
explicit compressed_pair(first_param_type x) : base(x) {}
|
||||
explicit compressed_pair(second_param_type y) : base(y) {}
|
||||
|
||||
first_reference first() {return base::first();}
|
||||
first_const_reference first() const {return base::first();}
|
||||
|
||||
second_reference second() {return base::second();}
|
||||
second_const_reference second() const {return base::second();}
|
||||
|
||||
void swap(compressed_pair& y) { base::swap(y); }
|
||||
};
|
||||
|
||||
// JM
|
||||
// Partial specialisation for case where T1 == T2:
|
||||
//
|
||||
template <class T>
|
||||
class compressed_pair<T, T>
|
||||
: private details::compressed_pair_imp<T, T,
|
||||
::boost::details::compressed_pair_switch<
|
||||
T,
|
||||
T,
|
||||
::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
|
||||
::boost::is_empty<T>::value,
|
||||
::boost::is_empty<T>::value>::value>
|
||||
{
|
||||
private:
|
||||
typedef details::compressed_pair_imp<T, T,
|
||||
::boost::details::compressed_pair_switch<
|
||||
T,
|
||||
T,
|
||||
::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
|
||||
::boost::is_empty<T>::value,
|
||||
::boost::is_empty<T>::value>::value> base;
|
||||
public:
|
||||
typedef T first_type;
|
||||
typedef T second_type;
|
||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||
typedef typename call_traits<first_type>::reference first_reference;
|
||||
typedef typename call_traits<second_type>::reference second_reference;
|
||||
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair() : base() {}
|
||||
compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
|
||||
explicit compressed_pair(first_param_type x) : base(x) {}
|
||||
|
||||
first_reference first() {return base::first();}
|
||||
first_const_reference first() const {return base::first();}
|
||||
|
||||
second_reference second() {return base::second();}
|
||||
second_const_reference second() const {return base::second();}
|
||||
|
||||
void swap(compressed_pair& y) { base::swap(y); }
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
inline
|
||||
void
|
||||
swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
} // boost
|
||||
|
||||
#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||
|
||||
|
35
include/boost/detail/ob_call_traits.hpp
Normal file
35
include/boost/detail/ob_call_traits.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// Crippled version for crippled compilers:
|
||||
//
|
||||
#ifndef BOOST_OB_CALL_TRAITS_HPP
|
||||
#define BOOST_OB_CALL_TRAITS_HPP
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{
|
||||
|
||||
template <typename T>
|
||||
struct call_traits
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef const T& param_type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_OB_CALL_TRAITS_HPP
|
69
include/boost/detail/ob_compressed_pair.hpp
Normal file
69
include/boost/detail/ob_compressed_pair.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// this version crippled for use with crippled compilers - John Maddock Jan 2000.
|
||||
|
||||
#ifndef BOOST_OB_COMPRESSED_PAIR_HPP
|
||||
#define BOOST_OB_COMPRESSED_PAIR_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#ifndef BOOST_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_CALL_TRAITS_HPP
|
||||
#include <boost/call_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair
|
||||
{
|
||||
private:
|
||||
T1 _first;
|
||||
T2 _second;
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
typedef T2 second_type;
|
||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
||||
typedef typename call_traits<first_type>::reference first_reference;
|
||||
typedef typename call_traits<second_type>::reference second_reference;
|
||||
typedef typename call_traits<first_type>::const_reference first_const_reference;
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair() : _first(), _second() {}
|
||||
compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
|
||||
explicit compressed_pair(first_param_type x) : _first(x), _second() {}
|
||||
//explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
|
||||
|
||||
first_reference first() { return _first; }
|
||||
first_const_reference first() const { return _first; }
|
||||
|
||||
second_reference second() { return _second; }
|
||||
second_const_reference second() const { return _second; }
|
||||
|
||||
void swap(compressed_pair& y)
|
||||
{
|
||||
using std::swap;
|
||||
swap(_first, y._first);
|
||||
swap(_second, y._second);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
||||
{
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
} // boost
|
||||
|
||||
#endif // BOOST_OB_COMPRESSED_PAIR_HPP
|
||||
|
559
include/boost/operators.hpp
Normal file
559
include/boost/operators.hpp
Normal file
@ -0,0 +1,559 @@
|
||||
// Boost operators.hpp header file ----------------------------------------//
|
||||
|
||||
// (C) Copyright David Abrahams 1999. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
|
||||
// refactoring of compiler workarounds, additional documentation
|
||||
// (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
|
||||
// Dave Abrahams)
|
||||
// 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
|
||||
// Jeremy Siek (Dave Abrahams)
|
||||
// 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
|
||||
// (Mark Rodgers)
|
||||
// 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
|
||||
// 10 Jun 00 Support for the base class chaining technique was added
|
||||
// (Aleksey Gurtovoy). See documentation and the comments below
|
||||
// for the details.
|
||||
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||
// 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
|
||||
// specializations of dividable, subtractable, modable (Ed Brey)
|
||||
// 17 Nov 99 Add comments (Beman Dawes)
|
||||
// Remove unnecessary specialization of operators<> (Ed Brey)
|
||||
// 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
|
||||
// operators.(Beman Dawes)
|
||||
// 12 Nov 99 Add operators templates (Ed Brey)
|
||||
// 11 Nov 99 Add single template parameter version for compilers without
|
||||
// partial specialization (Beman Dawes)
|
||||
// 10 Nov 99 Initial version
|
||||
|
||||
// 10 Jun 00:
|
||||
// An additional optional template parameter was added to most of
|
||||
// operator templates to support the base class chaining technique (see
|
||||
// documentation for the details). Unfortunately, a straightforward
|
||||
// implementation of this change would have broken compatibility with the
|
||||
// previous version of the library by making it impossible to use the same
|
||||
// template name (e.g. 'addable') for both the 1- and 2-argument versions of
|
||||
// an operator template. This implementation solves the backward-compatibility
|
||||
// issue at the cost of some simplicity.
|
||||
//
|
||||
// One of the complications is an existence of special auxiliary class template
|
||||
// 'is_chained_base<>' (see 'detail' namespace below), which is used
|
||||
// to determine whether its template parameter is a library's operator template
|
||||
// or not. You have to specialize 'is_chained_base<>' for each new
|
||||
// operator template you add to the library.
|
||||
//
|
||||
// However, most of the non-trivial implementation details are hidden behind
|
||||
// several local macros defined below, and as soon as you understand them,
|
||||
// you understand the whole library implementation.
|
||||
|
||||
#ifndef BOOST_OPERATORS_HPP
|
||||
#define BOOST_OPERATORS_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
#pragma set woff 1234
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
|
||||
class empty_base {};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
// In this section we supply the xxxx1 and xxxx2 forms of the operator
|
||||
// templates, which are explicitly targeted at the 1-type-argument and
|
||||
// 2-type-argument operator forms, respectively. Some compilers get confused
|
||||
// when inline friend functions are overloaded in namespaces other than the
|
||||
// global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
|
||||
// these templates must go in the global namespace.
|
||||
|
||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
namespace boost
|
||||
{
|
||||
#endif
|
||||
|
||||
// Basic operator classes (contributed by Dave Abrahams) ------------------//
|
||||
|
||||
// Note that friend functions defined in a class are implicitly inline.
|
||||
// See the C++ std, 11.4 [class.friend] paragraph 5
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct less_than_comparable2 : B
|
||||
{
|
||||
friend bool operator<=(const T& x, const U& y) { return !(x > y); }
|
||||
friend bool operator>=(const T& x, const U& y) { return !(x < y); }
|
||||
friend bool operator>(const U& x, const T& y) { return y < x; }
|
||||
friend bool operator<(const U& x, const T& y) { return y > x; }
|
||||
friend bool operator<=(const U& x, const T& y) { return !(y < x); }
|
||||
friend bool operator>=(const U& x, const T& y) { return !(y > x); }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct less_than_comparable1 : B
|
||||
{
|
||||
friend bool operator>(const T& x, const T& y) { return y < x; }
|
||||
friend bool operator<=(const T& x, const T& y) { return !(y < x); }
|
||||
friend bool operator>=(const T& x, const T& y) { return !(x < y); }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct equality_comparable2 : B
|
||||
{
|
||||
friend bool operator==(const U& y, const T& x) { return x == y; }
|
||||
friend bool operator!=(const U& y, const T& x) { return !(x == y); }
|
||||
friend bool operator!=(const T& y, const U& x) { return !(y == x); }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct equality_comparable1 : B
|
||||
{
|
||||
friend bool operator!=(const T& x, const T& y) { return !(x == y); }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct multipliable2 : B
|
||||
{
|
||||
friend T operator*(T x, const U& y) { return x *= y; }
|
||||
friend T operator*(const U& y, T x) { return x *= y; }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct multipliable1 : B
|
||||
{
|
||||
friend T operator*(T x, const T& y) { return x *= y; }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct addable2 : B
|
||||
{
|
||||
friend T operator+(T x, const U& y) { return x += y; }
|
||||
friend T operator+(const U& y, T x) { return x += y; }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct addable1 : B
|
||||
{
|
||||
friend T operator+(T x, const T& y) { return x += y; }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct subtractable2 : B
|
||||
{
|
||||
friend T operator-(T x, const U& y) { return x -= y; }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct subtractable1 : B
|
||||
{
|
||||
friend T operator-(T x, const T& y) { return x -= y; }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct dividable2 : B
|
||||
{
|
||||
friend T operator/(T x, const U& y) { return x /= y; }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct dividable1 : B
|
||||
{
|
||||
friend T operator/(T x, const T& y) { return x /= y; }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct modable2 : B
|
||||
{
|
||||
friend T operator%(T x, const U& y) { return x %= y; }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct modable1 : B
|
||||
{
|
||||
friend T operator%(T x, const T& y) { return x %= y; }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct xorable2 : B
|
||||
{
|
||||
friend T operator^(T x, const U& y) { return x ^= y; }
|
||||
friend T operator^(const U& y, T x) { return x ^= y; }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct xorable1 : B
|
||||
{
|
||||
friend T operator^(T x, const T& y) { return x ^= y; }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct andable2 : B
|
||||
{
|
||||
friend T operator&(T x, const U& y) { return x &= y; }
|
||||
friend T operator&(const U& y, T x) { return x &= y; }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct andable1 : B
|
||||
{
|
||||
friend T operator&(T x, const T& y) { return x &= y; }
|
||||
};
|
||||
|
||||
template <class T, class U, class B = ::boost::detail::empty_base>
|
||||
struct orable2 : B
|
||||
{
|
||||
friend T operator|(T x, const U& y) { return x |= y; }
|
||||
friend T operator|(const U& y, T x) { return x |= y; }
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct orable1 : B
|
||||
{
|
||||
friend T operator|(T x, const T& y) { return x |= y; }
|
||||
};
|
||||
|
||||
// incrementable and decrementable contributed by Jeremy Siek
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct incrementable : B
|
||||
{
|
||||
friend T operator++(T& x, int)
|
||||
{
|
||||
incrementable_type tmp(x);
|
||||
++x;
|
||||
return tmp;
|
||||
}
|
||||
private: // The use of this typedef works around a Borland bug
|
||||
typedef T incrementable_type;
|
||||
};
|
||||
|
||||
template <class T, class B = ::boost::detail::empty_base>
|
||||
struct decrementable : B
|
||||
{
|
||||
friend T operator--(T& x, int)
|
||||
{
|
||||
decrementable_type tmp(x);
|
||||
--x;
|
||||
return tmp;
|
||||
}
|
||||
private: // The use of this typedef works around a Borland bug
|
||||
typedef T decrementable_type;
|
||||
};
|
||||
|
||||
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
|
||||
|
||||
template <class T, class P, class B = ::boost::detail::empty_base>
|
||||
struct dereferenceable : B
|
||||
{
|
||||
P operator->() const
|
||||
{
|
||||
return &*static_cast<const T&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class I, class R, class B = ::boost::detail::empty_base>
|
||||
struct indexable : B
|
||||
{
|
||||
R operator[](I n) const
|
||||
{
|
||||
return *(static_cast<const T&>(*this) + n);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
} // namespace boost
|
||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
|
||||
|
||||
// BOOST_IMPORT_TEMPLATE1/BOOST_IMPORT_TEMPLATE2 -
|
||||
//
|
||||
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
|
||||
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
|
||||
// for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
|
||||
// two-argument forms. Note that these macros expect to be invoked from within
|
||||
// boost.
|
||||
|
||||
#if defined(BOOST_NO_OPERATORS_IN_NAMESPACE)
|
||||
|
||||
# if defined(BOOST_NO_USING_TEMPLATE)
|
||||
|
||||
// Because a Borland C++ 5.5 bug prevents a using declaration from working,
|
||||
// we are forced to use inheritance for that compiler.
|
||||
# define BOOST_IMPORT_TEMPLATE2(template_name) \
|
||||
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||
struct template_name : ::template_name<T, U, B> {};
|
||||
|
||||
# define BOOST_IMPORT_TEMPLATE1(template_name) \
|
||||
template <class T, class B = ::boost::detail::empty_base> \
|
||||
struct template_name : ::template_name<T, B> {};
|
||||
|
||||
# else
|
||||
|
||||
// Otherwise, bring the names in with a using-declaration to avoid
|
||||
// stressing the compiler
|
||||
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
|
||||
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
|
||||
|
||||
# endif // BOOST_NO_USING_TEMPLATE
|
||||
|
||||
#else // !BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
|
||||
// The template is already in boost so we have nothing to do.
|
||||
# define BOOST_IMPORT_TEMPLATE2(template_name)
|
||||
# define BOOST_IMPORT_TEMPLATE1(template_name)
|
||||
|
||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
|
||||
//
|
||||
// Here's where we put it all together, defining the xxxx forms of the templates
|
||||
// in namespace boost. We also define specializations of is_chained_base<> for
|
||||
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
||||
// neccessary.
|
||||
//
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
// is_chained_base<> - a traits class used to distinguish whether an operator
|
||||
// template argument is being used for base class chaining, or is specifying a
|
||||
// 2nd argument type.
|
||||
|
||||
namespace boost {
|
||||
// A type parameter is used instead of a plain bool because Borland's compiler
|
||||
// didn't cope well with the more obvious non-type template parameter.
|
||||
namespace detail {
|
||||
struct true_t {};
|
||||
struct false_t {};
|
||||
} // namespace detail
|
||||
|
||||
// Unspecialized version assumes that most types are not being used for base
|
||||
// class chaining. We specialize for the operator templates defined in this
|
||||
// library.
|
||||
template<class T> struct is_chained_base {
|
||||
typedef ::boost::detail::false_t value;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
// Import a 2-type-argument operator template into boost (if neccessary) and
|
||||
// provide a specialization of 'is_chained_base<>' for it.
|
||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||
BOOST_IMPORT_TEMPLATE2(template_name2) \
|
||||
template<class T, class U, class B> \
|
||||
struct is_chained_base< ::boost::template_name2<T, U, B> > { \
|
||||
typedef ::boost::detail::true_t value; \
|
||||
};
|
||||
|
||||
// Import a 1-type-argument operator template into boost (if neccessary) and
|
||||
// provide a specialization of 'is_chained_base<>' for it.
|
||||
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||
BOOST_IMPORT_TEMPLATE1(template_name1) \
|
||||
template<class T, class B> \
|
||||
struct is_chained_base< ::boost::template_name1<T, B> > { \
|
||||
typedef ::boost::detail::true_t value; \
|
||||
};
|
||||
|
||||
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
|
||||
// can be used for specifying both 1-argument and 2-argument forms. Requires the
|
||||
// existence of two previously defined class templates named '<template_name>1'
|
||||
// and '<template_name>2' which must implement the corresponding 1- and 2-
|
||||
// argument forms.
|
||||
//
|
||||
// The template type parameter O == is_chained_base<U>::value is used to
|
||||
// distinguish whether the 2nd argument to <template_name> is being used for
|
||||
// base class chaining from another boost operator template or is describing a
|
||||
// 2nd operand type. O == true_t only when U is actually an another operator
|
||||
// template from the library. Partial specialization is used to select an
|
||||
// implementation in terms of either '<template_name>1' or '<template_name>2'.
|
||||
//
|
||||
|
||||
# define BOOST_OPERATOR_TEMPLATE(template_name) \
|
||||
template <class T \
|
||||
,class U = T \
|
||||
,class B = ::boost::detail::empty_base \
|
||||
,class O = typename is_chained_base<U>::value \
|
||||
> \
|
||||
struct template_name : template_name##2<T, U, B> {}; \
|
||||
\
|
||||
template<class T, class U, class B> \
|
||||
struct template_name<T, U, B, ::boost::detail::true_t> \
|
||||
: template_name##1<T, U> {}; \
|
||||
\
|
||||
template <class T, class B> \
|
||||
struct template_name<T, T, B, ::boost::detail::false_t> \
|
||||
: template_name##1<T, B> {}; \
|
||||
\
|
||||
template<class T, class U, class B, class O> \
|
||||
struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
|
||||
typedef ::boost::detail::true_t value; \
|
||||
}; \
|
||||
\
|
||||
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
|
||||
BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
||||
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||
BOOST_IMPORT_TEMPLATE2(template_name2)
|
||||
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||
BOOST_IMPORT_TEMPLATE1(template_name1)
|
||||
|
||||
// In this case we can only assume that template_name<> is equivalent to the
|
||||
// more commonly needed template_name1<> form.
|
||||
# define BOOST_OPERATOR_TEMPLATE(template_name) \
|
||||
template <class T, class B = ::boost::detail::empty_base> \
|
||||
struct template_name : template_name##1<T, B> {};
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
|
||||
BOOST_OPERATOR_TEMPLATE(equality_comparable)
|
||||
BOOST_OPERATOR_TEMPLATE(multipliable)
|
||||
BOOST_OPERATOR_TEMPLATE(addable)
|
||||
BOOST_OPERATOR_TEMPLATE(subtractable)
|
||||
BOOST_OPERATOR_TEMPLATE(dividable)
|
||||
BOOST_OPERATOR_TEMPLATE(modable)
|
||||
BOOST_OPERATOR_TEMPLATE(xorable)
|
||||
BOOST_OPERATOR_TEMPLATE(andable)
|
||||
BOOST_OPERATOR_TEMPLATE(orable)
|
||||
|
||||
BOOST_OPERATOR_TEMPLATE1(incrementable)
|
||||
BOOST_OPERATOR_TEMPLATE1(decrementable)
|
||||
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
|
||||
|
||||
// indexable doesn't follow the patterns above (it has 4 template arguments), so
|
||||
// we just write out the compiler hacks explicitly.
|
||||
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||
# ifdef BOOST_NO_USING_TEMPLATE
|
||||
template <class T, class I, class R, class B = ::boost::detail::empty_base>
|
||||
struct indexable : ::indexable<T,I,R,B> {};
|
||||
# else
|
||||
using ::indexable;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T, class I, class R, class B>
|
||||
struct is_chained_base< ::boost::indexable<T, I, R, B> > {
|
||||
typedef ::boost::detail::true_t operator_template_type;
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef BOOST_OPERATOR_TEMPLATE
|
||||
#undef BOOST_OPERATOR_TEMPLATE2
|
||||
#undef BOOST_OPERATOR_TEMPLATE1
|
||||
#undef BOOST_IMPORT_TEMPLATE1
|
||||
#undef BOOST_IMPORT_TEMPLATE2
|
||||
|
||||
// The following 'operators' classes can only be used portably if the derived class
|
||||
// declares ALL of the required member operators.
|
||||
template <class T, class U>
|
||||
struct operators2
|
||||
: less_than_comparable2<T,U
|
||||
, equality_comparable2<T,U
|
||||
, addable2<T,U
|
||||
, subtractable2<T,U
|
||||
, multipliable2<T,U
|
||||
, dividable2<T,U
|
||||
, modable2<T,U
|
||||
, orable2<T,U
|
||||
, andable2<T,U
|
||||
, xorable2<T,U
|
||||
> > > > > > > > > > {};
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T, class U = T>
|
||||
struct operators : operators2<T, U> {};
|
||||
|
||||
template <class T> struct operators<T, T>
|
||||
#else
|
||||
template <class T> struct operators
|
||||
#endif
|
||||
: less_than_comparable<T
|
||||
, equality_comparable<T
|
||||
, addable<T
|
||||
, subtractable<T
|
||||
, multipliable<T
|
||||
, dividable<T
|
||||
, modable<T
|
||||
, orable<T
|
||||
, andable<T
|
||||
, xorable<T
|
||||
, incrementable<T
|
||||
, decrementable<T
|
||||
> > > > > > > > > > > > {};
|
||||
|
||||
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
|
||||
template <class T,
|
||||
class V,
|
||||
class D = std::ptrdiff_t,
|
||||
class P = V*,
|
||||
class R = V&>
|
||||
struct forward_iterator_helper
|
||||
: equality_comparable<T
|
||||
, incrementable<T
|
||||
, dereferenceable<T,P
|
||||
, boost::iterator<std::forward_iterator_tag, V, D
|
||||
> > > > {};
|
||||
|
||||
template <class T,
|
||||
class V,
|
||||
class D = std::ptrdiff_t,
|
||||
class P = V*,
|
||||
class R = V&>
|
||||
struct bidirectional_iterator_helper
|
||||
: equality_comparable<T
|
||||
, incrementable<T
|
||||
, decrementable<T
|
||||
, dereferenceable<T,P
|
||||
, boost::iterator<std::bidirectional_iterator_tag, V, D
|
||||
> > > > > {};
|
||||
|
||||
template <class T,
|
||||
class V,
|
||||
class D = std::ptrdiff_t,
|
||||
class P = V*,
|
||||
class R = V&>
|
||||
struct random_access_iterator_helper
|
||||
: equality_comparable<T
|
||||
, less_than_comparable<T
|
||||
, incrementable<T
|
||||
, decrementable<T
|
||||
, dereferenceable<T,P
|
||||
, addable2<T,D
|
||||
, subtractable2<T,D
|
||||
, indexable<T,D,R
|
||||
, boost::iterator<std::random_access_iterator_tag, V, D
|
||||
> > > > > > > > >
|
||||
{
|
||||
#ifndef __BORLANDC__
|
||||
friend D requires_difference_operator(const T& x, const T& y) {
|
||||
return x - y;
|
||||
}
|
||||
#endif
|
||||
}; // random_access_iterator_helper
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(__sgi) && !defined(__GNUC__)
|
||||
#pragma reset woff 1234
|
||||
#endif
|
||||
|
||||
#endif // BOOST_OPERATORS_HPP
|
69
include/boost/utility.hpp
Normal file
69
include/boost/utility.hpp
Normal file
@ -0,0 +1,69 @@
|
||||
// boost utility.hpp header file -------------------------------------------//
|
||||
|
||||
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
|
||||
// and distribute this software is granted provided this copyright
|
||||
// notice appears in all copies. This software is provided "as is" without
|
||||
// express or implied warranty, and with no claim as to its suitability for
|
||||
// any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Classes appear in alphabetical order
|
||||
|
||||
// Revision History
|
||||
// 26 Jan 00 protected noncopyable destructor added (Miki Jovanovic)
|
||||
// 10 Dec 99 next() and prior() templates added (Dave Abrahams)
|
||||
// 30 Aug 99 moved cast templates to cast.hpp (Beman Dawes)
|
||||
// 3 Aug 99 cast templates added
|
||||
// 20 Jul 99 name changed to utility.hpp
|
||||
// 9 Jun 99 protected noncopyable default ctor
|
||||
// 2 Jun 99 Initial Version. Class noncopyable only contents (Dave Abrahams)
|
||||
|
||||
#ifndef BOOST_UTILITY_HPP
|
||||
#define BOOST_UTILITY_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef> // for size_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// next() and prior() template functions -----------------------------------//
|
||||
|
||||
// Helper functions for classes like bidirectional iterators not supporting
|
||||
// operator+ and operator-.
|
||||
//
|
||||
// Usage:
|
||||
// const std::list<T>::iterator p = get_some_iterator();
|
||||
// const std::list<T>::iterator prev = boost::prior(p);
|
||||
|
||||
// Contributed by Dave Abrahams
|
||||
|
||||
template <class T>
|
||||
T next(T x) { return ++x; }
|
||||
|
||||
template <class T>
|
||||
T prior(T x) { return --x; }
|
||||
|
||||
|
||||
// class noncopyable -------------------------------------------------------//
|
||||
|
||||
// Private copy constructor and copy assignment ensure classes derived from
|
||||
// class noncopyable cannot be copied.
|
||||
|
||||
// Contributed by Dave Abrahams
|
||||
|
||||
class noncopyable
|
||||
{
|
||||
protected:
|
||||
noncopyable(){}
|
||||
~noncopyable(){}
|
||||
private: // emphasize the following members are private
|
||||
noncopyable( const noncopyable& );
|
||||
const noncopyable& operator=( const noncopyable& );
|
||||
}; // noncopyable
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UTILITY_HPP
|
||||
|
169
iterators_test.cpp
Normal file
169
iterators_test.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
// Demonstrate and test boost/operators.hpp on std::iterators --------------//
|
||||
|
||||
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
using namespace boost;
|
||||
|
||||
|
||||
template <class T, class R, class P>
|
||||
struct test_iter
|
||||
: public boost::random_access_iterator_helper<
|
||||
test_iter<T,R,P>, T, std::ptrdiff_t, P, R>
|
||||
{
|
||||
typedef test_iter self;
|
||||
typedef R Reference;
|
||||
typedef std::ptrdiff_t Distance;
|
||||
|
||||
public:
|
||||
test_iter(T* i) : _i(i) { }
|
||||
test_iter(const self& x) : _i(x._i) { }
|
||||
self& operator=(const self& x) { _i = x._i; return *this; }
|
||||
Reference operator*() const { return *_i; }
|
||||
self& operator++() { ++_i; return *this; }
|
||||
self& operator--() { --_i; return *this; }
|
||||
self& operator+=(Distance n) { _i += n; return *this; }
|
||||
self& operator-=(Distance n) { _i -= n; return *this; }
|
||||
bool operator==(const self& x) const { return _i == x._i; }
|
||||
bool operator<(const self& x) const { return _i < x._i; }
|
||||
friend Distance operator-(const self& x, const self& y) {
|
||||
return x._i - y._i;
|
||||
}
|
||||
protected:
|
||||
T* _i;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
string array[] = { "apple", "orange", "pear", "peach", "grape", "plum" };
|
||||
{
|
||||
test_iter<string,string&,string*> i = array,
|
||||
ie = array + sizeof(array)/sizeof(string);
|
||||
|
||||
// Tests for all of the operators added by random_access_iterator_helper
|
||||
|
||||
// test i++
|
||||
while (i != ie)
|
||||
cout << *i++ << " ";
|
||||
cout << endl;
|
||||
i = array;
|
||||
|
||||
// test i--
|
||||
while (ie != i) {
|
||||
ie--;
|
||||
cout << *ie << " ";
|
||||
}
|
||||
cout << endl;
|
||||
ie = array + sizeof(array)/sizeof(string);
|
||||
|
||||
// test i->m
|
||||
while (i != ie) {
|
||||
cout << i->size() << " ";
|
||||
++i;
|
||||
}
|
||||
cout << endl;
|
||||
i = array;
|
||||
|
||||
// test i + n
|
||||
while (i < ie) {
|
||||
cout << *i << " ";
|
||||
i = i + 2;
|
||||
}
|
||||
cout << endl;
|
||||
i = array;
|
||||
|
||||
// test n + i
|
||||
while (i < ie) {
|
||||
cout << *i << " ";
|
||||
i = ptrdiff_t(2) + i;
|
||||
}
|
||||
cout << endl;
|
||||
i = array;
|
||||
|
||||
// test i - n
|
||||
while (ie > i) {
|
||||
ie = ie - 2;
|
||||
cout << *ie << " ";
|
||||
}
|
||||
cout << endl;
|
||||
ie = array + sizeof(array)/sizeof(string);
|
||||
|
||||
// test i[n]
|
||||
for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j)
|
||||
cout << i[j] << " ";
|
||||
cout << endl;
|
||||
}
|
||||
{
|
||||
test_iter<string, const string&, const string*> i = array,
|
||||
ie = array + sizeof(array)/sizeof(string);
|
||||
|
||||
// Tests for all of the operators added by random_access_iterator_helper
|
||||
|
||||
// test i++
|
||||
while (i != ie)
|
||||
cout << *i++ << " ";
|
||||
cout << endl;
|
||||
i = array;
|
||||
|
||||
// test i--
|
||||
while (ie != i) {
|
||||
ie--;
|
||||
cout << *ie << " ";
|
||||
}
|
||||
cout << endl;
|
||||
ie = array + sizeof(array)/sizeof(string);
|
||||
|
||||
// test i->m
|
||||
while (i != ie) {
|
||||
cout << i->size() << " ";
|
||||
++i;
|
||||
}
|
||||
cout << endl;
|
||||
i = array;
|
||||
|
||||
// test i + n
|
||||
while (i < ie) {
|
||||
cout << *i << " ";
|
||||
i = i + 2;
|
||||
}
|
||||
cout << endl;
|
||||
i = array;
|
||||
|
||||
// test n + i
|
||||
while (i < ie) {
|
||||
cout << *i << " ";
|
||||
i = ptrdiff_t(2) + i;
|
||||
}
|
||||
cout << endl;
|
||||
i = array;
|
||||
|
||||
// test i - n
|
||||
while (ie > i) {
|
||||
ie = ie - 2;
|
||||
cout << *ie << " ";
|
||||
}
|
||||
cout << endl;
|
||||
ie = array + sizeof(array)/sizeof(string);
|
||||
|
||||
// test i[n]
|
||||
for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j)
|
||||
cout << i[j] << " ";
|
||||
cout << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
38
noncopyable_test.cpp
Normal file
38
noncopyable_test.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
// boost class noncopyable test program ------------------------------------//
|
||||
|
||||
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
|
||||
// and distribute this software is granted provided this copyright
|
||||
// notice appears in all copies. This software is provided "as is" without
|
||||
// express or implied warranty, and with no claim as to its suitability for
|
||||
// any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 9 Jun 99 Add unnamed namespace
|
||||
// 2 Jun 99 Initial Version
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// This program demonstrates compiler errors resulting from trying to copy
|
||||
// construct or copy assign a class object derived from class noncopyable.
|
||||
|
||||
namespace
|
||||
{
|
||||
class DontTreadOnMe : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
DontTreadOnMe() { std::cout << "defanged!" << std::endl; }
|
||||
}; // DontTreadOnMe
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
DontTreadOnMe object1;
|
||||
DontTreadOnMe object2(object1);
|
||||
object1 = object2;
|
||||
return 0;
|
||||
} // main
|
||||
|
481
operators_test.cpp
Normal file
481
operators_test.cpp
Normal file
@ -0,0 +1,481 @@
|
||||
// Demonstrate and test boost/operators.hpp -------------------------------//
|
||||
|
||||
// (C) Copyright Beman Dawes 1999. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 04 Jun 00 Added regression test for a bug I found (David Abrahams)
|
||||
// 17 Jun 00 Fix for broken compilers (Aleksey Gurtovoy)
|
||||
// ?? ??? 00 Major update to randomly test all one- and two- argument forms by
|
||||
// wrapping integral types and comparing the results of operations to
|
||||
// the results for the raw types (David Abrahams)
|
||||
// 12 Dec 99 Minor update, output confirmation message.
|
||||
// 15 Nov 99 Initial version
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <boost/min_rand.hpp>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
// avoiding a template version of true_value so as to not confuse VC++
|
||||
int true_value(int x) { return x; }
|
||||
long true_value(long x) { return x; }
|
||||
signed char true_value(signed char x) { return x; }
|
||||
unsigned int true_value(unsigned int x) { return x; }
|
||||
unsigned long true_value(unsigned long x) { return x; }
|
||||
unsigned char true_value(unsigned char x) { return x; }
|
||||
|
||||
// The use of operators<> here tended to obscure interactions with certain
|
||||
// compiler bugs
|
||||
template <class T>
|
||||
class Wrapped1 : boost::operators<Wrapped1<T> >
|
||||
{
|
||||
public:
|
||||
explicit Wrapped1( T v = T() ) : _value(v) {}
|
||||
T value() const { return _value; }
|
||||
|
||||
bool operator<(const Wrapped1& x) const { return _value < x._value; }
|
||||
bool operator==(const Wrapped1& x) const { return _value == x._value; }
|
||||
|
||||
Wrapped1& operator+=(const Wrapped1& x)
|
||||
{ _value += x._value; return *this; }
|
||||
Wrapped1& operator-=(const Wrapped1& x)
|
||||
{ _value -= x._value; return *this; }
|
||||
Wrapped1& operator*=(const Wrapped1& x)
|
||||
{ _value *= x._value; return *this; }
|
||||
Wrapped1& operator/=(const Wrapped1& x)
|
||||
{ _value /= x._value; return *this; }
|
||||
Wrapped1& operator%=(const Wrapped1& x)
|
||||
{ _value %= x._value; return *this; }
|
||||
Wrapped1& operator|=(const Wrapped1& x)
|
||||
{ _value |= x._value; return *this; }
|
||||
Wrapped1& operator&=(const Wrapped1& x)
|
||||
{ _value &= x._value; return *this; }
|
||||
Wrapped1& operator^=(const Wrapped1& x)
|
||||
{ _value ^= x._value; return *this; }
|
||||
Wrapped1& operator++() { ++_value; return *this; }
|
||||
Wrapped1& operator--() { --_value; return *this; }
|
||||
|
||||
private:
|
||||
T _value;
|
||||
};
|
||||
template <class T>
|
||||
T true_value(Wrapped1<T> x) { return x.value(); }
|
||||
|
||||
template <class T, class U>
|
||||
class Wrapped2 :
|
||||
boost::operators<Wrapped2<T, U> >,
|
||||
boost::operators2<Wrapped2<T, U>, U>
|
||||
{
|
||||
public:
|
||||
explicit Wrapped2( T v = T() ) : _value(v) {}
|
||||
T value() const { return _value; }
|
||||
|
||||
bool operator<(const Wrapped2& x) const { return _value < x._value; }
|
||||
bool operator==(const Wrapped2& x) const { return _value == x._value; }
|
||||
|
||||
Wrapped2& operator+=(const Wrapped2& x)
|
||||
{ _value += x._value; return *this; }
|
||||
Wrapped2& operator-=(const Wrapped2& x)
|
||||
{ _value -= x._value; return *this; }
|
||||
Wrapped2& operator*=(const Wrapped2& x)
|
||||
{ _value *= x._value; return *this; }
|
||||
Wrapped2& operator/=(const Wrapped2& x)
|
||||
{ _value /= x._value; return *this; }
|
||||
Wrapped2& operator%=(const Wrapped2& x)
|
||||
{ _value %= x._value; return *this; }
|
||||
Wrapped2& operator|=(const Wrapped2& x)
|
||||
{ _value |= x._value; return *this; }
|
||||
Wrapped2& operator&=(const Wrapped2& x)
|
||||
{ _value &= x._value; return *this; }
|
||||
Wrapped2& operator^=(const Wrapped2& x)
|
||||
{ _value ^= x._value; return *this; }
|
||||
Wrapped2& operator++() { ++_value; return *this; }
|
||||
Wrapped2& operator--() { --_value; return *this; }
|
||||
|
||||
bool operator<(U u) const { return _value < u; }
|
||||
bool operator>(U u) const { return _value > u; }
|
||||
bool operator==(U u) const { return _value == u; }
|
||||
Wrapped2& operator+=(U u) { _value += u; return *this; }
|
||||
Wrapped2& operator-=(U u) { _value -= u; return *this; }
|
||||
Wrapped2& operator*=(U u) { _value *= u; return *this; }
|
||||
Wrapped2& operator/=(U u) { _value /= u; return *this; }
|
||||
Wrapped2& operator%=(U u) { _value %= u; return *this; }
|
||||
Wrapped2& operator|=(U u) { _value |= u; return *this; }
|
||||
Wrapped2& operator&=(U u) { _value &= u; return *this; }
|
||||
Wrapped2& operator^=(U u) { _value ^= u; return *this; }
|
||||
|
||||
private:
|
||||
T _value;
|
||||
};
|
||||
template <class T, class U>
|
||||
T true_value(Wrapped2<T,U> x) { return x.value(); }
|
||||
|
||||
// MyInt uses only the single template-argument form of all_operators<>
|
||||
typedef Wrapped1<int> MyInt;
|
||||
|
||||
typedef Wrapped2<long, long> MyLong;
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
assert(true_value(y1) == true_value(y2));
|
||||
assert(true_value(x1) == true_value(x2));
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
assert((x1 < y1) == (x2 < y2));
|
||||
assert((x1 <= y1) == (x2 <= y2));
|
||||
assert((x1 >= y1) == (x2 >= y2));
|
||||
assert((x1 > y1) == (x2 > y2));
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_less_than_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
test_less_than_comparable_aux(x1, y1, x2, y2);
|
||||
test_less_than_comparable_aux(y1, x1, y2, x2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
assert((x1 == y1) == (x2 == y2));
|
||||
assert((x1 != y1) == (x2 != y2));
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_equality_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
test_equality_comparable_aux(x1, y1, x2, y2);
|
||||
test_equality_comparable_aux(y1, x1, y2, x2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
assert((x1 * y1).value() == (x2 * y2));
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_multipliable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
test_multipliable_aux(x1, y1, x2, y2);
|
||||
test_multipliable_aux(y1, x1, y2, x2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_addable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
assert((x1 + y1).value() == (x2 + y2));
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_addable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
test_addable_aux(x1, y1, x2, y2);
|
||||
test_addable_aux(y1, x1, y2, x2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
assert((x1 - y1).value() == x2 - y2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
if (y2 != 0)
|
||||
assert((x1 / y1).value() == x2 / y2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
if (y2 != 0)
|
||||
assert((x1 / y1).value() == x2 / y2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
assert((x1 ^ y1).value() == (x2 ^ y2));
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_xorable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
test_xorable_aux(x1, y1, x2, y2);
|
||||
test_xorable_aux(y1, x1, y2, x2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
assert((x1 & y1).value() == (x2 & y2));
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_andable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
test_andable_aux(x1, y1, x2, y2);
|
||||
test_andable_aux(y1, x1, y2, x2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
assert((x1 | y1).value() == (x2 | y2));
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
sanity_check(x1, y1, x2, y2);
|
||||
test_orable_aux(x1, y1, x2, y2);
|
||||
test_orable_aux(y1, x1, y2, x2);
|
||||
}
|
||||
|
||||
template <class X1, class X2>
|
||||
void test_incrementable(X1 x1, X2 x2)
|
||||
{
|
||||
sanity_check(x1, x1, x2, x2);
|
||||
assert(x1++.value() == x2++);
|
||||
assert(x1.value() == x2);
|
||||
}
|
||||
|
||||
template <class X1, class X2>
|
||||
void test_decrementable(X1 x1, X2 x2)
|
||||
{
|
||||
sanity_check(x1, x1, x2, x2);
|
||||
assert(x1--.value() == x2--);
|
||||
assert(x1.value() == x2);
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_all(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
test_less_than_comparable(x1, y1, x2, y2);
|
||||
test_equality_comparable(x1, y1, x2, y2);
|
||||
test_multipliable(x1, y1, x2, y2);
|
||||
test_addable(x1, y1, x2, y2);
|
||||
test_subtractable(x1, y1, x2, y2);
|
||||
test_dividable(x1, y1, x2, y2);
|
||||
test_modable(x1, y1, x2, y2);
|
||||
test_xorable(x1, y1, x2, y2);
|
||||
test_andable(x1, y1, x2, y2);
|
||||
test_orable(x1, y1, x2, y2);
|
||||
test_incrementable(x1, x2);
|
||||
test_decrementable(x1, x2);
|
||||
}
|
||||
|
||||
template <class Big, class Small>
|
||||
struct tester
|
||||
{
|
||||
void operator()(boost::min_rand& randomizer) const
|
||||
{
|
||||
Big b1 = Big(randomizer());
|
||||
Big b2 = Big(randomizer());
|
||||
Small s = Small(randomizer());
|
||||
|
||||
test_all(Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2);
|
||||
test_all(Wrapped2<Big, Small>(b1), s, b1, s);
|
||||
}
|
||||
};
|
||||
|
||||
// added as a regression test. We had a bug which this uncovered.
|
||||
struct Point
|
||||
: boost::addable<Point,
|
||||
boost::subtractable<Point> >
|
||||
{
|
||||
Point( int h, int v ) : h(h), v(v) {}
|
||||
Point() :h(0), v(0) {}
|
||||
const Point& operator+=( const Point& rhs ) { h += rhs.h; v += rhs.v; return *this; }
|
||||
const Point& operator-=( const Point& rhs ) { h -= rhs.h; v -= rhs.v; return *this; }
|
||||
|
||||
int h;
|
||||
int v;
|
||||
};
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
// workaround for MSVC bug; for some reasons the compiler doesn't instantiate
|
||||
// inherited operator templates at the moment it must, so the following
|
||||
// explicit instantiations force it to do that.
|
||||
|
||||
#if defined(BOOST_MSVC) && (_MSC_VER <= 1200)
|
||||
template Wrapped1<int>;
|
||||
template Wrapped1<long>;
|
||||
template Wrapped1<unsigned int>;
|
||||
template Wrapped1<unsigned long>;
|
||||
|
||||
template Wrapped2<int, int>;
|
||||
template Wrapped2<int, signed char>;
|
||||
template Wrapped2<long, signed char>;
|
||||
template Wrapped2<long, int>;
|
||||
template Wrapped2<long, long>;
|
||||
template Wrapped2<unsigned int, unsigned int>;
|
||||
template Wrapped2<unsigned int, unsigned char>;
|
||||
template Wrapped2<unsigned long, unsigned int>;
|
||||
template Wrapped2<unsigned long, unsigned char>;
|
||||
template Wrapped2<unsigned long, unsigned long>;
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#error This program is pointless when NDEBUG disables assert()!
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
// Regression test.
|
||||
Point x;
|
||||
x = x + Point(3, 4);
|
||||
x = x - Point(3, 4);
|
||||
|
||||
for (int n = 0; n < 10000; ++n)
|
||||
{
|
||||
boost::min_rand r;
|
||||
tester<long, int>()(r);
|
||||
tester<long, signed char>()(r);
|
||||
tester<long, long>()(r);
|
||||
tester<int, int>()(r);
|
||||
tester<int, signed char>()(r);
|
||||
|
||||
tester<unsigned long, unsigned int>()(r);
|
||||
tester<unsigned long, unsigned char>()(r);
|
||||
tester<unsigned long, unsigned long>()(r);
|
||||
tester<unsigned int, unsigned int>()(r);
|
||||
tester<unsigned int, unsigned char>()(r);
|
||||
}
|
||||
|
||||
MyInt i1(1);
|
||||
MyInt i2(2);
|
||||
MyInt i;
|
||||
|
||||
assert( i1.value() == 1 );
|
||||
assert( i2.value() == 2 );
|
||||
assert( i.value() == 0 );
|
||||
|
||||
i = i2;
|
||||
assert( i.value() == 2 );
|
||||
assert( i2 == i );
|
||||
assert( i1 != i2 );
|
||||
assert( i1 < i2 );
|
||||
assert( i1 <= i2 );
|
||||
assert( i <= i2 );
|
||||
assert( i2 > i1 );
|
||||
assert( i2 >= i1 );
|
||||
assert( i2 >= i );
|
||||
|
||||
i = i1 + i2; assert( i.value() == 3 );
|
||||
i = i + i2; assert( i.value() == 5 );
|
||||
i = i - i1; assert( i.value() == 4 );
|
||||
i = i * i2; assert( i.value() == 8 );
|
||||
i = i / i2; assert( i.value() == 4 );
|
||||
i = i % (i - i1); assert( i.value() == 1 );
|
||||
i = i2 + i2; assert( i.value() == 4 );
|
||||
i = i1 | i2 | i; assert( i.value() == 7 );
|
||||
i = i & i2; assert( i.value() == 2 );
|
||||
i = i + i1; assert( i.value() == 3 );
|
||||
i = i ^ i1; assert( i.value() == 2 );
|
||||
i = (i+i1)*(i2|i1); assert( i.value() == 9 );
|
||||
|
||||
MyLong j1(1);
|
||||
MyLong j2(2);
|
||||
MyLong j;
|
||||
|
||||
assert( j1.value() == 1 );
|
||||
assert( j2.value() == 2 );
|
||||
assert( j.value() == 0 );
|
||||
|
||||
j = j2;
|
||||
assert( j.value() == 2 );
|
||||
|
||||
assert( j2 == j );
|
||||
assert( 2 == j );
|
||||
assert( j2 == 2 );
|
||||
assert( j == j2 );
|
||||
assert( j1 != j2 );
|
||||
assert( j1 != 2 );
|
||||
assert( 1 != j2 );
|
||||
assert( j1 < j2 );
|
||||
assert( 1 < j2 );
|
||||
assert( j1 < 2 );
|
||||
assert( j1 <= j2 );
|
||||
assert( 1 <= j2 );
|
||||
assert( j1 <= j );
|
||||
assert( j <= j2 );
|
||||
assert( 2 <= j2 );
|
||||
assert( j <= 2 );
|
||||
assert( j2 > j1 );
|
||||
assert( 2 > j1 );
|
||||
assert( j2 > 1 );
|
||||
assert( j2 >= j1 );
|
||||
assert( 2 >= j1 );
|
||||
assert( j2 >= 1 );
|
||||
assert( j2 >= j );
|
||||
assert( 2 >= j );
|
||||
assert( j2 >= 2 );
|
||||
|
||||
assert( (j1 + 2) == 3 );
|
||||
assert( (1 + j2) == 3 );
|
||||
j = j1 + j2; assert( j.value() == 3 );
|
||||
|
||||
assert( (j + 2) == 5 );
|
||||
assert( (3 + j2) == 5 );
|
||||
j = j + j2; assert( j.value() == 5 );
|
||||
|
||||
assert( (j - 1) == 4 );
|
||||
j = j - j1; assert( j.value() == 4 );
|
||||
|
||||
assert( (j * 2) == 8 );
|
||||
assert( (4 * j2) == 8 );
|
||||
j = j * j2; assert( j.value() == 8 );
|
||||
|
||||
assert( (j / 2) == 4 );
|
||||
j = j / j2; assert( j.value() == 4 );
|
||||
|
||||
assert( (j % 3) == 1 );
|
||||
j = j % (j - j1); assert( j.value() == 1 );
|
||||
|
||||
j = j2 + j2; assert( j.value() == 4 );
|
||||
|
||||
assert( (1 | j2 | j) == 7 );
|
||||
assert( (j1 | 2 | j) == 7 );
|
||||
assert( (j1 | j2 | 4) == 7 );
|
||||
j = j1 | j2 | j; assert( j.value() == 7 );
|
||||
|
||||
assert( (7 & j2) == 2 );
|
||||
assert( (j & 2) == 2 );
|
||||
j = j & j2; assert( j.value() == 2 );
|
||||
|
||||
j = j | j1; assert( j.value() == 3 );
|
||||
|
||||
assert( (3 ^ j1) == 2 );
|
||||
assert( (j ^ 1) == 2 );
|
||||
j = j ^ j1; assert( j.value() == 2 );
|
||||
|
||||
j = (j+j1)*(j2|j1); assert( j.value() == 9 );
|
||||
|
||||
std::cout << "0 errors detected\n";
|
||||
return 0;
|
||||
}
|
623
type_traits_test.cpp
Normal file
623
type_traits_test.cpp
Normal file
@ -0,0 +1,623 @@
|
||||
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
|
||||
// Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/compressed_pair.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma option -w-ccc -w-rch -w-eff -w-aus
|
||||
#endif
|
||||
|
||||
//
|
||||
// define tests here
|
||||
unsigned failures = 0;
|
||||
|
||||
#define value_test(v, x) if(v == x) /*std::cout << "checking value of " << #x << "...OK" << std::endl*/;\
|
||||
else{++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;}
|
||||
|
||||
#define type_test(v, x) if(is_same<v, x>::value) /*std::cout << "checking type of " << #x << "...OK" << std::endl*/;\
|
||||
else{++failures; std::cout << "checking type of " << #x << "...failed (type was: " << typeid(is_same<v, x>).name() << ")" << std::endl;}
|
||||
|
||||
template <typename T, bool isarray = false>
|
||||
struct call_traits_test
|
||||
{
|
||||
static void assert_construct(call_traits<T>::param_type val);
|
||||
};
|
||||
|
||||
template <typename T, bool isarray>
|
||||
void call_traits_test<T, isarray>::assert_construct(call_traits<T>::param_type val)
|
||||
{
|
||||
//
|
||||
// this is to check that the call_traits assertions are valid:
|
||||
T t(val);
|
||||
call_traits<T>::value_type v(t);
|
||||
call_traits<T>::reference r(t);
|
||||
call_traits<T>::const_reference cr(t);
|
||||
call_traits<T>::param_type p(t);
|
||||
call_traits<T>::value_type v2(v);
|
||||
call_traits<T>::value_type v3(r);
|
||||
call_traits<T>::value_type v4(p);
|
||||
call_traits<T>::reference r2(v);
|
||||
call_traits<T>::reference r3(r);
|
||||
call_traits<T>::const_reference cr2(v);
|
||||
call_traits<T>::const_reference cr3(r);
|
||||
call_traits<T>::const_reference cr4(cr);
|
||||
call_traits<T>::const_reference cr5(p);
|
||||
call_traits<T>::param_type p2(v);
|
||||
call_traits<T>::param_type p3(r);
|
||||
call_traits<T>::param_type p4(p);
|
||||
}
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <typename T>
|
||||
struct call_traits_test<T, true>
|
||||
{
|
||||
static void assert_construct(call_traits<T>::param_type val);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void call_traits_test<T, true>::assert_construct(call_traits<T>::param_type val)
|
||||
{
|
||||
//
|
||||
// this is to check that the call_traits assertions are valid:
|
||||
T t;
|
||||
call_traits<T>::value_type v(t);
|
||||
call_traits<T>::reference r(t);
|
||||
call_traits<T>::const_reference cr(t);
|
||||
call_traits<T>::param_type p(t);
|
||||
call_traits<T>::value_type v2(v);
|
||||
call_traits<T>::value_type v3(r);
|
||||
call_traits<T>::value_type v4(p);
|
||||
call_traits<T>::reference r2(v);
|
||||
call_traits<T>::reference r3(r);
|
||||
call_traits<T>::const_reference cr2(v);
|
||||
call_traits<T>::const_reference cr3(r);
|
||||
call_traits<T>::const_reference cr4(cr);
|
||||
call_traits<T>::const_reference cr5(p);
|
||||
call_traits<T>::param_type p2(v);
|
||||
call_traits<T>::param_type p3(r);
|
||||
call_traits<T>::param_type p4(p);
|
||||
}
|
||||
#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// Since there is no compiler support, we should specialize:
|
||||
// is_enum for all enumerations (is_enum implies is_POD)
|
||||
// is_union for all unions
|
||||
// is_empty for all empty composites
|
||||
// is_POD for all PODs (except enums) (is_POD implies has_*)
|
||||
// has_* for any UDT that has that trait and is not POD
|
||||
|
||||
enum enum_UDT{ one, two, three };
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace boost {
|
||||
template <> struct is_enum<enum_UDT>
|
||||
{ static const bool value = true; };
|
||||
}
|
||||
#endif
|
||||
struct UDT
|
||||
{
|
||||
UDT();
|
||||
~UDT();
|
||||
UDT(const UDT&);
|
||||
UDT& operator=(const UDT&);
|
||||
int i;
|
||||
|
||||
void f1();
|
||||
int f2();
|
||||
int f3(int);
|
||||
int f4(int, float);
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
struct POD_UDT { int x; };
|
||||
namespace boost {
|
||||
template <> struct is_POD<POD_UDT>
|
||||
{ static const bool value = true; };
|
||||
}
|
||||
#endif
|
||||
struct empty_UDT
|
||||
{
|
||||
~empty_UDT(){};
|
||||
};
|
||||
namespace boost {
|
||||
//template <> struct is_empty<empty_UDT>
|
||||
//{ static const bool value = true; };
|
||||
// this type is not POD, so we have to specialize the has_* individually
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <> struct has_trivial_constructor<empty_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct has_trivial_copy<empty_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct has_trivial_assign<empty_UDT>
|
||||
{ static const bool value = true; };
|
||||
}
|
||||
#endif
|
||||
|
||||
struct empty_POD_UDT{};
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace boost {
|
||||
template <> struct is_empty<empty_POD_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct is_POD<empty_POD_UDT>
|
||||
{ static const bool value = true; };
|
||||
}
|
||||
#endif
|
||||
union union_UDT
|
||||
{
|
||||
int x;
|
||||
double y;
|
||||
~union_UDT();
|
||||
};
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace boost {
|
||||
template <> struct is_union<union_UDT>
|
||||
{ static const bool value = true; };
|
||||
}
|
||||
#endif
|
||||
union POD_union_UDT
|
||||
{
|
||||
int x;
|
||||
double y;
|
||||
};
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace boost {
|
||||
template <> struct is_union<POD_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct is_POD<POD_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
}
|
||||
#endif
|
||||
union empty_union_UDT
|
||||
{
|
||||
~empty_union_UDT();
|
||||
};
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace boost {
|
||||
template <> struct is_union<empty_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct is_empty<empty_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
// this type is not POD, so we have to specialize the has_* individually
|
||||
template <> struct has_trivial_constructor<empty_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct has_trivial_copy<empty_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct has_trivial_assign<empty_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
}
|
||||
#endif
|
||||
union empty_POD_union_UDT{};
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
namespace boost {
|
||||
template <> struct is_union<empty_POD_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct is_empty<empty_POD_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct is_POD<empty_POD_union_UDT>
|
||||
{ static const bool value = true; };
|
||||
#endif
|
||||
}
|
||||
// Steve: All comments that I (Steve Cleary) have added below are prefixed with
|
||||
// "Steve:" The failures that BCB4 has on the tests are due to Borland's
|
||||
// not considering cv-qual's as a part of the type -- they are considered
|
||||
// compiler hints only. These failures should be fixed before long.
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Checking type operations..." << std::endl << std::endl;
|
||||
|
||||
type_test(int, remove_reference<int>::type)
|
||||
type_test(const int, remove_reference<const int>::type)
|
||||
type_test(int, remove_reference<int&>::type)
|
||||
type_test(const int, remove_reference<const int&>::type)
|
||||
type_test(volatile int, remove_reference<volatile int&>::type)
|
||||
type_test(int, remove_const<const int>::type)
|
||||
// Steve: fails on BCB4
|
||||
type_test(volatile int, remove_const<volatile int>::type)
|
||||
// Steve: fails on BCB4
|
||||
type_test(volatile int, remove_const<const volatile int>::type)
|
||||
type_test(int, remove_const<int>::type)
|
||||
type_test(int*, remove_const<int* const>::type)
|
||||
type_test(int, remove_volatile<volatile int>::type)
|
||||
// Steve: fails on BCB4
|
||||
type_test(const int, remove_volatile<const int>::type)
|
||||
// Steve: fails on BCB4
|
||||
type_test(const int, remove_volatile<const volatile int>::type)
|
||||
type_test(int, remove_volatile<int>::type)
|
||||
type_test(int*, remove_volatile<int* volatile>::type)
|
||||
type_test(int, remove_cv<volatile int>::type)
|
||||
type_test(int, remove_cv<const int>::type)
|
||||
type_test(int, remove_cv<const volatile int>::type)
|
||||
type_test(int, remove_cv<int>::type)
|
||||
type_test(int*, remove_cv<int* volatile>::type)
|
||||
type_test(int*, remove_cv<int* const>::type)
|
||||
type_test(int*, remove_cv<int* const volatile>::type)
|
||||
type_test(const int *, remove_cv<const int * const>::type)
|
||||
type_test(int, remove_bounds<int>::type)
|
||||
type_test(int*, remove_bounds<int*>::type)
|
||||
type_test(int, remove_bounds<int[3]>::type)
|
||||
type_test(int[3], remove_bounds<int[2][3]>::type)
|
||||
|
||||
type_test(const int, call_traits<int>::param_type)
|
||||
type_test(const char, call_traits<char>::param_type)
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
type_test(char&, call_traits<char&>::param_type)
|
||||
type_test(const char&, call_traits<const char&>::param_type)
|
||||
#endif
|
||||
std::cout << std::endl << "Checking type properties..." << std::endl << std::endl;
|
||||
|
||||
value_test(false, is_const<int>::value)
|
||||
value_test(true, is_const<const int>::value)
|
||||
value_test(false, is_const<volatile int>::value)
|
||||
value_test(true, is_const<const volatile int>::value)
|
||||
|
||||
value_test(false, is_volatile<int>::value)
|
||||
value_test(false, is_volatile<const int>::value)
|
||||
value_test(true, is_volatile<volatile int>::value)
|
||||
value_test(true, is_volatile<const volatile int>::value)
|
||||
|
||||
value_test(true, is_void<void>::value)
|
||||
// Steve: fails on BCB4
|
||||
value_test(false, is_void<const void>::value)
|
||||
value_test(false, is_void<int>::value)
|
||||
|
||||
value_test(false, is_standard_unsigned_integral<UDT>::value)
|
||||
value_test(false, is_standard_unsigned_integral<void>::value)
|
||||
value_test(false, is_standard_unsigned_integral<bool>::value)
|
||||
value_test(false, is_standard_unsigned_integral<char>::value)
|
||||
value_test(false, is_standard_unsigned_integral<signed char>::value)
|
||||
value_test(true, is_standard_unsigned_integral<unsigned char>::value)
|
||||
value_test(false, is_standard_unsigned_integral<wchar_t>::value)
|
||||
value_test(false, is_standard_unsigned_integral<short>::value)
|
||||
value_test(true, is_standard_unsigned_integral<unsigned short>::value)
|
||||
value_test(false, is_standard_unsigned_integral<int>::value)
|
||||
value_test(true, is_standard_unsigned_integral<unsigned int>::value)
|
||||
value_test(false, is_standard_unsigned_integral<long>::value)
|
||||
value_test(true, is_standard_unsigned_integral<unsigned long>::value)
|
||||
value_test(false, is_standard_unsigned_integral<float>::value)
|
||||
value_test(false, is_standard_unsigned_integral<double>::value)
|
||||
value_test(false, is_standard_unsigned_integral<long double>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(false, is_standard_unsigned_integral<long long>::value)
|
||||
value_test(false, is_standard_unsigned_integral<unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(false, is_standard_unsigned_integral<__int64>::value)
|
||||
value_test(false, is_standard_unsigned_integral<unsigned __int64>::value)
|
||||
#endif
|
||||
|
||||
value_test(false, is_standard_signed_integral<UDT>::value)
|
||||
value_test(false, is_standard_signed_integral<void>::value)
|
||||
value_test(false, is_standard_signed_integral<bool>::value)
|
||||
value_test(false, is_standard_signed_integral<char>::value)
|
||||
value_test(true, is_standard_signed_integral<signed char>::value)
|
||||
value_test(false, is_standard_signed_integral<unsigned char>::value)
|
||||
value_test(false, is_standard_signed_integral<wchar_t>::value)
|
||||
value_test(true, is_standard_signed_integral<short>::value)
|
||||
value_test(false, is_standard_signed_integral<unsigned short>::value)
|
||||
value_test(true, is_standard_signed_integral<int>::value)
|
||||
value_test(false, is_standard_signed_integral<unsigned int>::value)
|
||||
value_test(true, is_standard_signed_integral<long>::value)
|
||||
value_test(false, is_standard_signed_integral<unsigned long>::value)
|
||||
value_test(false, is_standard_signed_integral<float>::value)
|
||||
value_test(false, is_standard_signed_integral<double>::value)
|
||||
value_test(false, is_standard_signed_integral<long double>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(false, is_standard_signed_integral<long long>::value)
|
||||
value_test(false, is_standard_signed_integral<unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(false, is_standard_signed_integral<__int64>::value)
|
||||
value_test(false, is_standard_signed_integral<unsigned __int64>::value)
|
||||
#endif
|
||||
|
||||
value_test(false, is_standard_arithmetic<UDT>::value)
|
||||
value_test(false, is_standard_arithmetic<void>::value)
|
||||
value_test(true, is_standard_arithmetic<bool>::value)
|
||||
value_test(true, is_standard_arithmetic<char>::value)
|
||||
value_test(true, is_standard_arithmetic<signed char>::value)
|
||||
value_test(true, is_standard_arithmetic<unsigned char>::value)
|
||||
value_test(true, is_standard_arithmetic<wchar_t>::value)
|
||||
value_test(true, is_standard_arithmetic<short>::value)
|
||||
value_test(true, is_standard_arithmetic<unsigned short>::value)
|
||||
value_test(true, is_standard_arithmetic<int>::value)
|
||||
value_test(true, is_standard_arithmetic<unsigned int>::value)
|
||||
value_test(true, is_standard_arithmetic<long>::value)
|
||||
value_test(true, is_standard_arithmetic<unsigned long>::value)
|
||||
value_test(true, is_standard_arithmetic<float>::value)
|
||||
value_test(true, is_standard_arithmetic<double>::value)
|
||||
value_test(true, is_standard_arithmetic<long double>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(false, is_standard_arithmetic<long long>::value)
|
||||
value_test(false, is_standard_arithmetic<unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(false, is_standard_arithmetic<__int64>::value)
|
||||
value_test(false, is_standard_arithmetic<unsigned __int64>::value)
|
||||
#endif
|
||||
|
||||
value_test(false, is_standard_fundamental<UDT>::value)
|
||||
value_test(true, is_standard_fundamental<void>::value)
|
||||
value_test(true, is_standard_fundamental<bool>::value)
|
||||
value_test(true, is_standard_fundamental<char>::value)
|
||||
value_test(true, is_standard_fundamental<signed char>::value)
|
||||
value_test(true, is_standard_fundamental<unsigned char>::value)
|
||||
value_test(true, is_standard_fundamental<wchar_t>::value)
|
||||
value_test(true, is_standard_fundamental<short>::value)
|
||||
value_test(true, is_standard_fundamental<unsigned short>::value)
|
||||
value_test(true, is_standard_fundamental<int>::value)
|
||||
value_test(true, is_standard_fundamental<unsigned int>::value)
|
||||
value_test(true, is_standard_fundamental<long>::value)
|
||||
value_test(true, is_standard_fundamental<unsigned long>::value)
|
||||
value_test(true, is_standard_fundamental<float>::value)
|
||||
value_test(true, is_standard_fundamental<double>::value)
|
||||
value_test(true, is_standard_fundamental<long double>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(false, is_standard_fundamental<long long>::value)
|
||||
value_test(false, is_standard_fundamental<unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(false, is_standard_fundamental<__int64>::value)
|
||||
value_test(false, is_standard_fundamental<unsigned __int64>::value)
|
||||
#endif
|
||||
|
||||
value_test(false, is_arithmetic<UDT>::value)
|
||||
value_test(true, is_arithmetic<char>::value)
|
||||
value_test(true, is_arithmetic<signed char>::value)
|
||||
value_test(true, is_arithmetic<unsigned char>::value)
|
||||
value_test(true, is_arithmetic<wchar_t>::value)
|
||||
value_test(true, is_arithmetic<short>::value)
|
||||
value_test(true, is_arithmetic<unsigned short>::value)
|
||||
value_test(true, is_arithmetic<int>::value)
|
||||
value_test(true, is_arithmetic<unsigned int>::value)
|
||||
value_test(true, is_arithmetic<long>::value)
|
||||
value_test(true, is_arithmetic<unsigned long>::value)
|
||||
value_test(true, is_arithmetic<float>::value)
|
||||
value_test(true, is_arithmetic<double>::value)
|
||||
value_test(true, is_arithmetic<long double>::value)
|
||||
value_test(true, is_arithmetic<bool>::value)
|
||||
#ifdef ULLONG_MAX
|
||||
value_test(true, is_arithmetic<long long>::value)
|
||||
value_test(true, is_arithmetic<unsigned long long>::value)
|
||||
#endif
|
||||
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||
value_test(true, is_arithmetic<__int64>::value)
|
||||
value_test(true, is_arithmetic<unsigned __int64>::value)
|
||||
#endif
|
||||
|
||||
value_test(false, is_array<int>::value)
|
||||
value_test(false, is_array<int*>::value)
|
||||
value_test(true, is_array<int[2]>::value)
|
||||
value_test(true, is_array<int[2][3]>::value)
|
||||
value_test(true, is_array<UDT[2]>::value)
|
||||
|
||||
typedef void(*f1)();
|
||||
typedef int(*f2)(int);
|
||||
typedef int(*f3)(int, bool);
|
||||
typedef void (UDT::*mf1)();
|
||||
typedef int (UDT::*mf2)();
|
||||
typedef int (UDT::*mf3)(int);
|
||||
typedef int (UDT::*mf4)(int, float);
|
||||
|
||||
value_test(false, is_pointer<int>::value)
|
||||
value_test(false, is_pointer<int&>::value)
|
||||
value_test(true, is_pointer<int*>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
|
||||
value_test(false, is_pointer<int*const>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
|
||||
value_test(false, is_pointer<int*volatile>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
|
||||
value_test(false, is_pointer<int*const volatile>::value)
|
||||
value_test(true, is_pointer<f1>::value)
|
||||
value_test(true, is_pointer<f2>::value)
|
||||
value_test(true, is_pointer<f3>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3
|
||||
value_test(false, is_pointer<mf1>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3
|
||||
value_test(false, is_pointer<mf2>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3
|
||||
value_test(false, is_pointer<mf3>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3
|
||||
value_test(false, is_pointer<mf4>::value)
|
||||
|
||||
value_test(false, is_reference<bool>::value)
|
||||
value_test(true, is_reference<int&>::value)
|
||||
value_test(true, is_reference<const int&>::value)
|
||||
value_test(true, is_reference<volatile int &>::value)
|
||||
|
||||
value_test(false, is_class<int>::value)
|
||||
value_test(false, is_class<const int>::value)
|
||||
value_test(false, is_class<volatile int>::value)
|
||||
value_test(false, is_class<int*>::value)
|
||||
value_test(false, is_class<int* const>::value)
|
||||
value_test(false, is_class<int[2]>::value)
|
||||
value_test(false, is_class<int&>::value)
|
||||
value_test(false, is_class<mf4>::value)
|
||||
value_test(false, is_class<f1>::value)
|
||||
value_test(false, is_class<enum_UDT>::value)
|
||||
value_test(true, is_class<UDT>::value)
|
||||
value_test(true, is_class<UDT const>::value)
|
||||
value_test(true, is_class<UDT volatile>::value)
|
||||
value_test(true, is_class<empty_UDT>::value)
|
||||
value_test(true, is_class<std::iostream>::value)
|
||||
value_test(false, is_class<UDT*>::value)
|
||||
value_test(false, is_class<UDT[2]>::value)
|
||||
value_test(false, is_class<UDT&>::value)
|
||||
|
||||
value_test(true, is_object<int>::value)
|
||||
value_test(true, is_object<UDT>::value)
|
||||
value_test(false, is_object<int&>::value)
|
||||
value_test(false, is_object<void>::value)
|
||||
value_test(true, is_standard_scalar<int>::value)
|
||||
value_test(true, is_extension_scalar<void*>::value)
|
||||
|
||||
value_test(false, is_enum<int>::value)
|
||||
value_test(true, is_enum<enum_UDT>::value)
|
||||
|
||||
value_test(false, is_member_pointer<f1>::value)
|
||||
value_test(false, is_member_pointer<f2>::value)
|
||||
value_test(false, is_member_pointer<f3>::value)
|
||||
value_test(true, is_member_pointer<mf1>::value)
|
||||
value_test(true, is_member_pointer<mf2>::value)
|
||||
value_test(true, is_member_pointer<mf3>::value)
|
||||
value_test(true, is_member_pointer<mf4>::value)
|
||||
|
||||
value_test(false, is_empty<int>::value)
|
||||
value_test(false, is_empty<int*>::value)
|
||||
value_test(false, is_empty<int&>::value)
|
||||
value_test(false, is_empty<int[2]>::value)
|
||||
value_test(false, is_empty<f1>::value)
|
||||
value_test(false, is_empty<mf1>::value)
|
||||
value_test(false, is_empty<UDT>::value)
|
||||
value_test(false, is_empty<std::iostream>::value)
|
||||
value_test(true, is_empty<empty_UDT>::value)
|
||||
value_test(false, is_empty<enum_UDT>::value)
|
||||
|
||||
value_test(true, has_trivial_constructor<int>::value)
|
||||
value_test(true, has_trivial_constructor<int*>::value)
|
||||
value_test(true, has_trivial_constructor<int*const>::value)
|
||||
value_test(true, has_trivial_constructor<const int>::value)
|
||||
value_test(true, has_trivial_constructor<volatile int>::value)
|
||||
value_test(true, has_trivial_constructor<int[2]>::value)
|
||||
value_test(true, has_trivial_constructor<int[3][2]>::value)
|
||||
value_test(true, has_trivial_constructor<int[2][4][5][6][3]>::value)
|
||||
value_test(true, has_trivial_constructor<f1>::value)
|
||||
value_test(true, has_trivial_constructor<mf2>::value)
|
||||
value_test(false, has_trivial_constructor<UDT>::value)
|
||||
value_test(true, has_trivial_constructor<empty_UDT>::value)
|
||||
value_test(true, has_trivial_constructor<enum_UDT>::value)
|
||||
|
||||
value_test(true, has_trivial_copy<int>::value)
|
||||
value_test(true, has_trivial_copy<int*>::value)
|
||||
value_test(true, has_trivial_copy<int*const>::value)
|
||||
value_test(true, has_trivial_copy<const int>::value)
|
||||
// Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
|
||||
value_test(true, has_trivial_copy<volatile int>::value)
|
||||
value_test(true, has_trivial_copy<int[2]>::value)
|
||||
value_test(true, has_trivial_copy<int[3][2]>::value)
|
||||
value_test(true, has_trivial_copy<int[2][4][5][6][3]>::value)
|
||||
value_test(true, has_trivial_copy<f1>::value)
|
||||
value_test(true, has_trivial_copy<mf2>::value)
|
||||
value_test(false, has_trivial_copy<UDT>::value)
|
||||
value_test(true, has_trivial_copy<empty_UDT>::value)
|
||||
value_test(true, has_trivial_copy<enum_UDT>::value)
|
||||
|
||||
value_test(true, has_trivial_assign<int>::value)
|
||||
value_test(true, has_trivial_assign<int*>::value)
|
||||
value_test(true, has_trivial_assign<int*const>::value)
|
||||
value_test(true, has_trivial_assign<const int>::value)
|
||||
// Steve: was 'false' -- should be 'true' via 3.9p3, 3.9p10
|
||||
value_test(true, has_trivial_assign<volatile int>::value)
|
||||
value_test(true, has_trivial_assign<int[2]>::value)
|
||||
value_test(true, has_trivial_assign<int[3][2]>::value)
|
||||
value_test(true, has_trivial_assign<int[2][4][5][6][3]>::value)
|
||||
value_test(true, has_trivial_assign<f1>::value)
|
||||
value_test(true, has_trivial_assign<mf2>::value)
|
||||
value_test(false, has_trivial_assign<UDT>::value)
|
||||
value_test(true, has_trivial_assign<empty_UDT>::value)
|
||||
value_test(true, has_trivial_assign<enum_UDT>::value)
|
||||
|
||||
value_test(true, has_trivial_destructor<int>::value)
|
||||
value_test(true, has_trivial_destructor<int*>::value)
|
||||
value_test(true, has_trivial_destructor<int*const>::value)
|
||||
value_test(true, has_trivial_destructor<const int>::value)
|
||||
value_test(true, has_trivial_destructor<volatile int>::value)
|
||||
value_test(true, has_trivial_destructor<int[2]>::value)
|
||||
value_test(true, has_trivial_destructor<int[3][2]>::value)
|
||||
value_test(true, has_trivial_destructor<int[2][4][5][6][3]>::value)
|
||||
value_test(true, has_trivial_destructor<f1>::value)
|
||||
value_test(true, has_trivial_destructor<mf2>::value)
|
||||
value_test(false, has_trivial_destructor<UDT>::value)
|
||||
value_test(false, has_trivial_destructor<empty_UDT>::value)
|
||||
value_test(true, has_trivial_destructor<enum_UDT>::value)
|
||||
|
||||
value_test(true, is_POD<int>::value)
|
||||
value_test(true, is_POD<int*>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9p10
|
||||
value_test(false, is_POD<int&>::value)
|
||||
value_test(true, is_POD<int*const>::value)
|
||||
value_test(true, is_POD<const int>::value)
|
||||
// Steve: was 'false', should be 'true', via 3.9p10
|
||||
value_test(true, is_POD<volatile int>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9p10
|
||||
value_test(false, is_POD<const int&>::value)
|
||||
value_test(true, is_POD<int[2]>::value)
|
||||
value_test(true, is_POD<int[3][2]>::value)
|
||||
value_test(true, is_POD<int[2][4][5][6][3]>::value)
|
||||
value_test(true, is_POD<f1>::value)
|
||||
value_test(true, is_POD<mf2>::value)
|
||||
value_test(false, is_POD<UDT>::value)
|
||||
value_test(false, is_POD<empty_UDT>::value)
|
||||
value_test(true, is_POD<enum_UDT>::value)
|
||||
|
||||
compressed_pair<int, double> cp1;
|
||||
compressed_pair<int, double> cp1b;
|
||||
swap(cp1, cp1b);
|
||||
compressed_pair<empty_UDT, int> cp2;
|
||||
compressed_pair<int, empty_UDT> cp3;
|
||||
compressed_pair<empty_UDT, empty_UDT> cp4;
|
||||
compressed_pair<empty_UDT, empty_POD_UDT> cp5;
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
int i;
|
||||
compressed_pair<int&, int&> cp6(i,i);
|
||||
compressed_pair<int, double[2]> cp7;
|
||||
cp7.first();
|
||||
double* pd = cp7.second();
|
||||
#endif
|
||||
value_test(true, (sizeof(compressed_pair<empty_UDT, int>) < sizeof(std::pair<empty_UDT, int>)))
|
||||
value_test(true, (sizeof(compressed_pair<int, empty_UDT>) < sizeof(std::pair<int, empty_UDT>)))
|
||||
value_test(true, (sizeof(compressed_pair<empty_UDT, empty_UDT>) < sizeof(std::pair<empty_UDT, empty_UDT>)))
|
||||
value_test(true, (sizeof(compressed_pair<empty_UDT, empty_POD_UDT>) < sizeof(std::pair<empty_UDT, empty_POD_UDT>)))
|
||||
|
||||
std::cout << std::endl << "Tests completed (" << failures << " failures)... press any key to exit";
|
||||
std::cin.get();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// instanciate some compressed pairs:
|
||||
template class boost::compressed_pair<int, double>;
|
||||
template class boost::compressed_pair<int, int>;
|
||||
template class boost::compressed_pair<empty_UDT, int>;
|
||||
template class boost::compressed_pair<int, empty_UDT>;
|
||||
template class boost::compressed_pair<empty_UDT, empty_UDT>;
|
||||
template class boost::compressed_pair<empty_UDT, empty_POD_UDT>;
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
//
|
||||
// now some for which only a few specific members can be instantiated,
|
||||
// first references:
|
||||
template double& compressed_pair<double, int&>::first();
|
||||
template int& compressed_pair<double, int&>::second();
|
||||
template compressed_pair<double, int&>::compressed_pair(int&);
|
||||
template compressed_pair<double, int&>::compressed_pair(call_traits<double>::param_type,int&);
|
||||
//
|
||||
// and then arrays:
|
||||
#ifndef __BORLANDC__
|
||||
template call_traits<int[2]>::reference compressed_pair<double, int[2]>::second();
|
||||
#endif
|
||||
template call_traits<double>::reference compressed_pair<double, int[2]>::first();
|
||||
template compressed_pair<double, int[2]>::compressed_pair(const double&);
|
||||
template compressed_pair<double, int[2]>::compressed_pair();
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
//
|
||||
// now check call_traits assertions by instantiating call_traits_test:
|
||||
template struct call_traits_test<int>;
|
||||
template struct call_traits_test<const int>;
|
||||
template struct call_traits_test<int*>;
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template struct call_traits_test<int&>;
|
||||
template struct call_traits_test<const int&>;
|
||||
// this doesn't work (yet) (JM):
|
||||
template struct call_traits_test<int[2], true>;
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user