Skip to content

Instantly share code, notes, and snippets.

@udaken
Last active January 20, 2019 21:29
Show Gist options
  • Save udaken/307c935d2c457674124f383f6b37ed31 to your computer and use it in GitHub Desktop.
Save udaken/307c935d2c457674124f383f6b37ed31 to your computer and use it in GitHub Desktop.
#include <iterator>
#include <vector>
#ifndef _MSC_VER
#define __forceinline __attribute__((always_inline))
#endif
template <int N>
struct unit
{
private:
struct tag {};
__forceinline
static const tag& instance()
{
static tag a;
return a;
}
public:
typedef const tag* iterator;
__forceinline
static iterator begin()
{
return &instance();
}
__forceinline
static iterator end()
{
return &instance() + 1;
}
};
template <class InputIt0
,class InputIt1
,class InputIt2 = typename unit<2>::iterator
,class InputIt3 = typename unit<3>::iterator
,class InputIt4 = typename unit<4>::iterator
,class InputIt5 = typename unit<5>::iterator
,class InputIt6 = typename unit<6>::iterator
,class InputIt7 = typename unit<7>::iterator
,class InputIt8 = typename unit<8>::iterator
,class InputIt9 = typename unit<9>::iterator
>
class direct_production
{
InputIt0 itr0_begin; InputIt0 itr0_end;
InputIt1 itr1_begin; InputIt1 itr1_end;
InputIt2 itr2_begin; InputIt2 itr2_end;
InputIt3 itr3_begin; InputIt3 itr3_end;
InputIt4 itr4_begin; InputIt4 itr4_end;
InputIt5 itr5_begin; InputIt5 itr5_end;
InputIt6 itr6_begin; InputIt6 itr6_end;
InputIt7 itr7_begin; InputIt7 itr7_end;
InputIt8 itr8_begin; InputIt8 itr8_end;
InputIt9 itr9_begin; InputIt9 itr9_end;
private:
direct_production();
public:
direct_production(
InputIt0 itr0_begin, InputIt0 itr0_end
,InputIt1 itr1_begin, InputIt1 itr1_end
,InputIt2 itr2_begin = unit<2>::begin(), InputIt2 itr2_end = unit<2>::end()
,InputIt3 itr3_begin = unit<3>::begin(), InputIt3 itr3_end = unit<3>::end()
,InputIt4 itr4_begin = unit<4>::begin(), InputIt4 itr4_end = unit<4>::end()
,InputIt5 itr5_begin = unit<5>::begin(), InputIt5 itr5_end = unit<5>::end()
,InputIt6 itr6_begin = unit<6>::begin(), InputIt6 itr6_end = unit<6>::end()
,InputIt7 itr7_begin = unit<7>::begin(), InputIt7 itr7_end = unit<7>::end()
,InputIt8 itr8_begin = unit<8>::begin(), InputIt8 itr8_end = unit<8>::end()
,InputIt9 itr9_begin = unit<9>::begin(), InputIt9 itr9_end = unit<9>::end()
)
: itr0_begin(itr0_begin), itr0_end(itr0_end)
, itr1_begin(itr1_begin), itr1_end(itr1_end)
, itr2_begin(itr2_begin), itr2_end(itr2_end)
, itr3_begin(itr3_begin), itr3_end(itr3_end)
, itr4_begin(itr4_begin), itr4_end(itr4_end)
, itr5_begin(itr5_begin), itr5_end(itr5_end)
, itr6_begin(itr6_begin), itr6_end(itr6_end)
, itr7_begin(itr7_begin), itr7_end(itr7_end)
, itr8_begin(itr8_begin), itr8_end(itr8_end)
, itr9_begin(itr9_begin), itr9_end(itr9_end)
{
}
class forward_iterator : std::forward_iterator_tag
{
const direct_production &parent;
InputIt0 itr0_current;
InputIt1 itr1_current;
InputIt2 itr2_current;
InputIt3 itr3_current;
InputIt4 itr4_current;
InputIt5 itr5_current;
InputIt6 itr6_current;
InputIt7 itr7_current;
InputIt8 itr8_current;
InputIt9 itr9_current;
public:
forward_iterator(const direct_production &parent
,InputIt0 itr0_current
,InputIt1 itr1_current
,InputIt2 itr2_current
,InputIt3 itr3_current
,InputIt4 itr4_current
,InputIt5 itr5_current
,InputIt6 itr6_current
,InputIt7 itr7_current
,InputIt8 itr8_current
,InputIt9 itr9_current
) : parent(parent)
, itr0_current(itr0_current)
, itr1_current(itr1_current)
, itr2_current(itr2_current)
, itr3_current(itr3_current)
, itr4_current(itr4_current)
, itr5_current(itr5_current)
, itr6_current(itr6_current)
, itr7_current(itr7_current)
, itr8_current(itr8_current)
, itr9_current(itr9_current)
{
}
forward_iterator(const forward_iterator &other)
: parent(other.parent)
, itr0_current(other.itr0_current)
, itr1_current(other.itr1_current)
, itr2_current(other.itr2_current)
, itr3_current(other.itr3_current)
, itr4_current(other.itr4_current)
, itr5_current(other.itr5_current)
, itr6_current(other.itr6_current)
, itr7_current(other.itr7_current)
, itr8_current(other.itr8_current)
, itr9_current(other.itr9_current)
{
}
bool operator ==(const forward_iterator &other) const
{
return (&parent) == (&other.parent)
&& itr0_current == other.itr0_current
&& itr1_current == other.itr1_current
&& itr2_current == other.itr2_current
&& itr3_current == other.itr3_current
&& itr4_current == other.itr4_current
&& itr5_current == other.itr5_current
&& itr6_current == other.itr6_current
&& itr7_current == other.itr7_current
&& itr8_current == other.itr8_current
&& itr9_current == other.itr9_current
;
}
bool operator !=(const forward_iterator &other) const
{
return !(*this == other);
}
forward_iterator &operator++()
{
++itr9_current ;
if (itr9_current != parent.itr9_end )
{
goto case9;
}
++itr8_current ;
if (itr8_current != parent.itr8_end )
{
goto case8;
}
++itr7_current ;
if (itr7_current != parent.itr7_end )
{
goto case7;
}
++itr6_current ;
if (itr6_current != parent.itr6_end )
{
goto case6;
}
++itr5_current ;
if (itr5_current != parent.itr5_end )
{
goto case5;
}
++itr4_current ;
if (itr4_current != parent.itr4_end )
{
goto case4;
}
++itr3_current ;
if (itr3_current != parent.itr3_end )
{
goto case3;
}
++itr2_current ;
if (itr2_current != parent.itr2_end )
{
goto case2;
}
++itr1_current;
if(itr1_current != parent.itr1_end )
{
goto case1;
}
++itr0_current;
if(itr0_current != parent.itr0_end )
{
goto case0;
}
return *this;
case0:
itr1_current = parent.itr1_begin;
case1:
itr2_current = parent.itr2_begin;
case2:
itr3_current = parent.itr3_begin;
case3:
itr4_current = parent.itr4_begin;
case4:
itr5_current = parent.itr5_begin;
case5:
itr6_current = parent.itr6_begin;
case6:
itr7_current = parent.itr7_begin;
case7:
itr8_current = parent.itr8_begin;
case8:
itr9_current = parent.itr9_begin;
case9:
return *this;
}
forward_iterator operator++(int)
{
forward_iterator tmp(*this);
++(*this);
return tmp;
}
template <size_t index>
struct index_to_type;
template <size_t index>
typename index_to_type<index>::type get() const;
template <>
struct index_to_type<0> { typedef InputIt0 type; };
template <>
InputIt0 get<0>() const { return itr0_current; }
template <>
struct index_to_type<1> { typedef InputIt1 type; };
template <>
InputIt1 get<1>() const { return itr1_current; }
template <>
struct index_to_type<2> { typedef InputIt2 type; };
template <>
InputIt2 get<2>() const { return itr2_current; }
template <>
struct index_to_type<3> { typedef InputIt3 type; };
template <>
InputIt3 get<3>() const { return itr3_current; }
template <>
struct index_to_type<4> { typedef InputIt4 type; };
template <>
InputIt4 get<4>() const { return itr4_current; }
template <>
struct index_to_type<5> { typedef InputIt5 type; };
template <>
InputIt5 get<5>() const { return itr5_current; }
template <>
struct index_to_type<6> { typedef InputIt6 type; };
template <>
InputIt6 get<6>() const { return itr6_current; }
template <>
struct index_to_type<7> { typedef InputIt7 type; };
template <>
InputIt7 get<7>() const { return itr7_current; }
template <>
struct index_to_type<8> { typedef InputIt8 type; };
template <>
InputIt8 get<8>() const { return itr8_current; }
template <>
struct index_to_type<9> { typedef InputIt9 type; };
template <>
InputIt9 get<9>() const { return itr9_current; }
};
typedef forward_iterator itarator;
forward_iterator begin() const
{
return forward_iterator(*this
, itr0_begin
, itr1_begin
, itr2_begin
, itr3_begin
, itr4_begin
, itr5_begin
, itr6_begin
, itr7_begin
, itr8_begin
, itr9_begin
);
}
forward_iterator end() const
{
return forward_iterator(*this
, itr0_end
, itr1_end
, itr2_end
, itr3_end
, itr4_end
, itr5_end
, itr6_end
, itr7_end
, itr8_end
, itr9_end
);
}
};
template <class InputIt0
, class InputIt1
>
direct_production<InputIt0
, InputIt1
> make_direct_production(InputIt0 itr0_begin, InputIt0 itr0_end
, InputIt1 itr1_begin, InputIt1 itr1_end
)
{
return direct_production<InputIt0
, InputIt1
>(itr0_begin,itr0_end
,itr1_begin, itr1_end
);
}
template <class InputIt0
, class InputIt1
, class InputIt2
>
direct_production<InputIt0
, InputIt1
, InputIt2
> make_direct_production(InputIt0 itr0_begin, InputIt0 itr0_end
, InputIt1 itr1_begin, InputIt1 itr1_end
, InputIt2 itr2_begin, InputIt2 itr2_end
)
{
return direct_production<InputIt0
, InputIt1
, InputIt2
>(itr0_begin,itr0_end
,itr1_begin, itr1_end
,itr2_begin, itr2_end
);
}
template <class InputIt0
, class InputIt1
, class InputIt2
, class InputIt3
>
direct_production<InputIt0
, InputIt1
, InputIt2
, InputIt3
> make_direct_production(InputIt0 itr0_begin, InputIt0 itr0_end
, InputIt1 itr1_begin, InputIt1 itr1_end
, InputIt2 itr2_begin, InputIt2 itr2_end
, InputIt3 itr3_begin, InputIt3 itr3_end
)
{
return direct_production<InputIt0
, InputIt1
, InputIt2
, InputIt3
>(itr0_begin,itr0_end
,itr1_begin, itr1_end
,itr2_begin, itr2_end
,itr3_begin, itr3_end
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment