--- /dev/null
+#ifndef GINTENLIB_INCLUDED_MEMBERWISE_SWAP_HPP_
+#define GINTENLIB_INCLUDED_MEMBERWISE_SWAP_HPP_
+
+/*
+
+ <gintenlib/memberwise_swap.hpp>
+
+ memberwise_swap : メンバ変数の swap
+
+ 宣言:
+ template< typename T, typename Args... >
+ void memberwise_swap( T& one, T& another, Args... mem_ptr... );
+
+ 機能:
+ one.swap( another ); を呼び出す friend 関数 swap を定義します
+
+*/
+
+#include <algorithm> // for std::swap
+
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+namespace gintenlib
+{
+ #define GINTENLIB_GEN_SWAP_( z, n, mp ) \
+ swap( one.*BOOST_PP_CAT( mp, n ), another.*BOOST_PP_CAT( mp, n ) );
+
+ #define GINTENLIB_GEN_( z, n, unused_ ) \
+ template<typename T, BOOST_PP_ENUM_PARAMS( n, typename M )> \
+ inline void memberwise_swap( T& one, T& another, \
+ BOOST_PP_ENUM_BINARY_PARAMS( n, M, T::*mp ) ) \
+ { \
+ using std::swap; \
+ BOOST_PP_REPEAT_FROM_TO( 0, n, GINTENLIB_GEN_SWAP_, mp ) \
+ }
+ // #define GINTENLIB_GEN_( z, n, unused_ )
+
+ BOOST_PP_REPEAT_FROM_TO( 1, 10, GINTENLIB_GEN_, _ )
+
+ #undef GINTENLIB_GEN_
+ #undef GINTENLIB_GEN_SWAP_
+
+} // namespace gintenlib
+
+#endif // #ifndef GINTENLIB_INCLUDED_MEMBERWISE_SWAP_HPP_
--- /dev/null
+#include "../gintenlib/memberwise_swap.hpp"
+
+// boost の単体テストフレームワーク
+#include <boost/test/minimal.hpp>
+
+#include <string>
+#include <boost/scoped_ptr.hpp>
+
+// 使用例(面倒なのでメンバ3個ので代表する)
+struct hoge
+{
+ // 内部データ構造体とか
+ struct data
+ {
+ explicit data( int x_ )
+ : x(x_){}
+
+ int x;
+ };
+
+ int i; // 組み込み型
+ std::string s; // assignable なクラス
+ boost::scoped_ptr<data> p; // noncopyable かつ swappable なクラス
+
+ hoge( int i_, const std::string& s_, int x )
+ : i( i_ ), s( s_ ), p( new data(x) ) {}
+
+ // 本体
+ void swap( hoge& other )
+ {
+ // 交換したい2オブジェクトに続けて、メンバ変数へのポインタを並べる
+ gintenlib::memberwise_swap( *this, other, &hoge::i, &hoge::s, &hoge::p );
+ }
+ friend void swap( hoge& one, hoge& another )
+ {
+ one.swap( another );
+ }
+
+}; // struct hoge
+
+// テスト本体
+int test_main( int, char** )
+{
+ hoge h1( 1, "foo", 23 ), h2( 2, "bar", 42 );
+ hoge::data *p1 = h1.p.get(), *p2 = h2.p.get();
+
+ // swap 呼び出し
+ swap( h1, h2 );
+
+ // 交換出来ているかチェック
+ BOOST_CHECK( h1.i == 2 && h2.i == 1 );
+ BOOST_CHECK( h1.s == "bar" && h2.s == "foo" );
+ BOOST_CHECK( h1.p.get() == p2 && h2.p.get() == p1 );
+
+ return 0;
+}