Last active
June 3, 2019 07:47
-
-
Save plasma-effect/0181a772f971329390091d71fa54fdda to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include<type_traits> | |
// copyright (c) 2019 plasma-effect | |
// Distributed under the Boost Software License, Version 1.0. | |
// (See http://www.boost.org/LICENSE_1_0.txt) | |
namespace auto_indexer | |
{ | |
enum | |
{ | |
set = 1, | |
get = 2 | |
}; | |
template<class Derived, class T, int flag = set | get>class indexer | |
{ | |
template<int flag>class return_t | |
{ | |
friend class indexer<Derived, T, flag>; | |
static_assert(0 < flag&& flag < 4, "flag error"); | |
return_t(Derived* p, std::size_t i) | |
{ | |
} | |
}; | |
template<>class return_t<set> | |
{ | |
friend class indexer<Derived, T, flag>; | |
Derived* ptr; | |
std::size_t index; | |
return_t(Derived* p, std::size_t i) :ptr(p), index(i) | |
{ | |
} | |
public: | |
decltype(auto) operator=(T&& value) | |
{ | |
return ptr->set(index, std::move(value)); | |
} | |
decltype(auto) operator=(T const& value) | |
{ | |
return ptr->set(index, value); | |
} | |
}; | |
template<>class return_t<get> | |
{ | |
friend class indexer<Derived, T, flag>; | |
Derived const* ptr; | |
std::size_t index; | |
return_t(Derived const* p, std::size_t i) :ptr(p), index(i) | |
{ | |
} | |
public: | |
operator T()const | |
{ | |
return ptr->get(index); | |
} | |
}; | |
template<>class return_t<set | get> | |
{ | |
friend class indexer<Derived, T, flag>; | |
Derived* ptr; | |
std::size_t index; | |
return_t(Derived* p, std::size_t i) :ptr(p), index(i) | |
{ | |
} | |
public: | |
decltype(auto) operator=(T&& value) | |
{ | |
return ptr->set(index, std::move(value)); | |
} | |
decltype(auto) operator=(T const& value) | |
{ | |
return ptr->set(index, value); | |
} | |
operator T()const | |
{ | |
return ptr->get(index); | |
} | |
}; | |
public: | |
auto operator[](std::size_t index) | |
{ | |
if constexpr (flag == get) | |
{ | |
return return_t<get>(static_cast<Derived const*>(this), index); | |
} | |
else | |
{ | |
return return_t<flag>(static_cast<Derived*>(this), index); | |
} | |
} | |
auto operator[](std::size_t index)const | |
{ | |
if constexpr (flag & get) | |
{ | |
return return_t<get>(static_cast<Derived const*>(this), index); | |
} | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment