aa

C++ code posted
created at 30 Aug 04:05, updated at 09 Sep 01:53

Edit | Back
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#pragma once

#include <type_traits>
#include <utility>

#include "detail/util.h"
#include "detail/swizzler.h"
#include "detail/functions.h"
#include "detail/binary_ops.h"
#include "detail/vector_base.h"

namespace vml {

template<typename T, size_t... Ns>
struct _MSC_FIX_EBO vector :
  public detail::vector_base_selector<T, Ns...>::base_type,
  public detail::builtin_func_lib<vector, T, Ns...>,
  public std::conditional<sizeof...(Ns) != 1, // no binary ops for promoted scalar
    detail::binary_vec_ops<vector<T, Ns...>, T>, detail::nothing>::type
{
  static constexpr auto num_components = sizeof...(Ns);

  using scalar_type = T;
  using vector_type = vector<T, Ns...>;
  using base_type = typename detail::vector_base_selector<T, Ns...>::base_type;
  using decay_type = typename std::conditional<num_components == 1, scalar_type, vector_type>::type;

  // bring in scope the union member
  using base_type::data;

  vector()
  {
    ((data[Ns] = 0), ...);
  }

  vector(typename std::conditional<num_components == 1, scalar_type, detail::nothing>::type s)
  {
    data[0] = s;
  }

  explicit vector(typename std::conditional<num_components != 1, scalar_type, detail::nothing>::type s)
  {
    ((data[Ns] = s), ...);
  }

  template<typename A0, typename... Args,
    class = typename std::enable_if<
      ((sizeof... (Args) >= 1) ||
      ((sizeof... (Args) == 0) && !std::is_scalar<A0>::value))
    >::type>
  explicit vector(A0&& a0, Args&&... args)
  {
    static_assert((sizeof...(args) < num_components), "too many arguments");

#define CTOR_FOLD
#ifdef CTOR_FOLD
    size_t i = 0;

     construct_at_index(i, detail::decay(std::forward<A0>(a0)));
    (construct_at_index(i, detail::decay(std::forward<Args>(args))), ...);
#else
    static_recurse<0>(std::forward<A0>(a0), std::forward<Args>(args)...);
#endif
  }

  scalar_type const operator[](size_t i) const
  {
    return data[i];
  }

  scalar_type& operator[](size_t i)
  {
    return data[i];
  }

  decay_type decay() const
  {
    return static_cast<const decay_type&>(*this);
  }

  operator typename std::conditional<num_components == 1, scalar_type, detail::nothing>::type() const
  {
    return data[0];
  }

  using self_type = vector_type;
#define Is Ns
#define HAS_UNARY_MUL
#include "detail/unary_ops.h"

  //TODO: add matrix multiply

private:
#ifdef CTOR_FOLD
  void construct_at_index(size_t &i, scalar_type arg)
  {
    data[i++] = arg;
  }

  template<typename Other, size_t... Other_Ns>
  void construct_at_index(size_t &i, const vector<Other, Other_Ns...> &arg)
  {
    constexpr auto other_num = vector<Other, Other_Ns...>::num_components;
    constexpr auto count = num_components <= other_num ? num_components : other_num;

    detail::static_for<0, count>()([&](size_t j) {
      data[i++] = arg.data[j];
    });
  }
#else
  template<size_t i>
  void construct_at_index(scalar_type arg)
  {
    data[i] = arg;
  }

  template<size_t i, typename Other, size_t... Other_Ns>
  void construct_at_index(const vector<Other, Other_Ns...> &arg)
  {
    constexpr auto other_num = vector<Other, Other_Ns...>::num_components;
    constexpr auto count = (i + other_num) > num_components ? num_components : (i + other_num);
    detail::static_for<i, count>()([&](size_t j) {
      data[j] = arg.data[j - i];
    });
  }

  template<size_t I, typename Arg0, typename... Args>
  void static_recurse(Arg0&& a0, Args&&... args)
  {
    construct_at_index<I>(detail::decay(std::forward<Arg0>(a0)));
    static_recurse<I + detail::get_size<Arg0>()>(std::forward<Args>(args)...);
  }

  template<size_t I>
  void static_recurse()
  {}
#endif
};

} // namespace vml

// needs to be after everything has been defined
#include "detail/traits.h"
3.65 KB in 6 ms with coderay