C++03 で C++0x の std::max_align_t をシミュレートする

C++ において、データのアライメントというのは極めて大事な概念です。*1
しかし、今までの C++ の規格では、その辺りのコードに必要な情報を得るための方法が少なく、
移植性を意識したコードを書こうと思ったら、 Boost 辺りに頼らなければいけませんでした。


そこで C++0x では、新しい識別子 alignof をはじめとして、
アライメント関連の規格がいろいろと定義されています。
その中の一つに で定義された std::max_align_t というのがあり、
これは要するに new 呼び出しで得られるポインタと同じアライメントを持つ型です。
で、ひょんなことから、この std::max_align_t が必要になったので、
どうにかこうにか C++03 の範囲でこの max_align_t を作ってみました。

#include <boost/cstdint.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/type_with_alignment.hpp>

namespace etude {
  // 最大の整数と、最大の浮動小数点数
  using boost::intmax_t;
  typedef long double floatmax_t;

  // 実装補助。一番長い組み込み型を選ぶ
  union max_align_t_
  {
    intmax_t i; floatmax_t f;
    void* p; void (*fp)();
    
    struct dummy {};
    int dummy::*mp; void (dummy::*mfp)();
  };
  
  // で、そのアライメントを満たす、より相応しい型を得る
  typedef boost::type_with_alignment<
    boost::alignment_of<max_align_t_>::value
  >::type max_align_t;

} // namespace etude

#include <iostream>

int main() {
  std::cout << sizeof(etude::max_align_t) << std::endl;
  std::cout << boost::alignment_of< etude::max_align_t >::value << std::endl;
}

やることは、組み込み型の中で考えられる限り最大のサイズとアライメントを持った union を作って、
その union のアライメントを持った最小限のサイズの型を得る、というものです。
といっても、あんまり詳しく調べてないので、これで本当に正しいかどうかは不明。
もし間違えてたらツッコんでくれると助かります。

追記 ( 10/29/2010 22:50 )

int が intmax_t より長いアライメントを持ってる可能性もあるし、こっちのほうがいいかな。

#include <boost/cstdint.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/type_with_alignment.hpp>

namespace etude {
  // 実装補助。一番長い組み込み型を選ぶ
  union max_align_t_
  {
    // 整数型
    short s; int i; long l; boost::intmax_t im;
    // 浮動小数点型
    float f; double d; long double ld;
    // ポインタ
    void* p; void (*fp)();
    // メンバポインタ
    struct dummy {};
    int dummy::*mp; void (dummy::*mfp)();
  };
  
  // で、そのアライメントを満たす型を得る
  typedef boost::type_with_alignment<
    boost::alignment_of<max_align_t_>::value
  >::type max_align_t;

} // namespace etude

#include <iostream>

int main() {
  std::cout << sizeof(etude::max_align_t) << std::endl;
  std::cout << boost::alignment_of< etude::max_align_t >::value << std::endl;
}