読者です 読者をやめる 読者になる 読者になる

ゆとりーなの日記

日記的な事を書いて行くと思はれる

いらんかった

昨日の話ですが、どう考えてもマップにする必要がなかったみたいなので全部ベクトルで書き換えました。ベクトルにしたのでremove_ifが使える様になった関係上空のベクトルを作る必要もなくなっていい感じです。

#include <cstdint>
#include <type_traits>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/remove_if.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/lambda.hpp>
#include <d3d9.h>

struct dimension2_drawable_tag {};
struct dimension3_drawable_tag {};
struct normal_drawable_tag {};
struct diffuse_drawable_tag {};
struct speculer_drawable_tag {};
struct tex1_drawable_tag {};
struct tex2_drawable_tag {};

// 全部ベクトルに置き換え
typedef boost::mpl::vector<
    boost::mpl::vector<dimension2_drawable_tag, boost::mpl::integral_c<std::uint32_t, D3DFVF_XYZRHW>>,
    boost::mpl::vector<dimension3_drawable_tag, boost::mpl::integral_c<std::uint32_t, D3DFVF_XYZ>>,
    boost::mpl::vector<normal_drawable_tag, boost::mpl::integral_c<std::uint32_t, D3DFVF_NORMAL>>,
    boost::mpl::vector<diffuse_drawable_tag, boost::mpl::integral_c<std::uint32_t, D3DFVF_DIFFUSE>>,
    boost::mpl::vector<speculer_drawable_tag, boost::mpl::integral_c<std::uint32_t, D3DFVF_SPECULAR>>,
    boost::mpl::vector<tex1_drawable_tag, boost::mpl::integral_c<std::uint32_t, D3DFVF_TEX1>>,
    boost::mpl::vector<tex2_drawable_tag, boost::mpl::integral_c<std::uint32_t, D3DFVF_TEX2>>> fvf_list;

template <typename List, std::size_t Size>
struct vertex {
};

// インデックスアクセス用の定数
enum fvf_index {
  kType,
  kValue
};

// 継承関係になければfalseを返す
// ベクトルにした関係上要素のアクセス方法が変わる
template <typename Lhs, typename Rhs>
struct fvf_is_base_of {
  typedef bool value_type;
  static const value_type value = !std::is_base_of<typename boost::mpl::at_c<Lhs, kType>::type, Rhs>::value;
};

template <typename Lhs, typename Rhs>
struct bitor_fvf_type {
  typedef std::uint32_t value_type;
  static const value_type value = typename Lhs::value | typename boost::mpl::at_c<Rhs, kValue>::type::value;
};

template <typename Drawable>
struct fvf_traits {
  // 要らないやつを消す方向に変更
  typedef typename boost::mpl::remove_if<fvf_list, 
                                         fvf_is_base_of<boost::mpl::_1, typename Drawable::drawable_tag>>::type fvf_list;
  typedef typename boost::mpl::fold<fvf_list, 
                                    boost::mpl::integral_c<std::uint32_t, 0>, 
                                    bitor_fvf_type<boost::mpl::_1, boost::mpl::_2>>::type fvf;
};

struct tag : public dimension2_drawable_tag, public diffuse_drawable_tag {};

struct box {
  typedef tag drawable_tag;
};

int main() {
  const std::uint32_t fvf = fvf_traits<box>::fvf::value; // D3DFVF_XYZRHW | D3DFVF_DIFFUSE
  return 0;
}