# `v2s(virtual2stack)-tec`
> virtual2stack-tec
## v2s-tec.h
#pragma once
#ifndef _V2S_TEC_H
#define _V2S_TEC_H
#ifdef _MSC_VER
#define fcal __fastcall
#else
#define fcal __attribute__((fastcall))
#endif
#define PUSH(T, x) x = this::push<T>(x)
namespace __argv_t_space__ {
/**
*
* # __fake_t_space__
*
* template toolstorage that :
* - fake_t<T>
* - is_overptr<T>::doseit
*
*/
namespace __fake_t_space__ {
/**
*
* # limit as ptr - when overptr
*
* overptr so use it as ptr to limit as ptr
*
*/
template <bool overptr, typename T>
struct limasptr {
using type = T*;
};
/**
*
* # limit as ptr - when not overptr
*
* not overptr so, use it as it self.
*
*/
template <typename T>
struct limasptr<false, T> {
using type = T;
};
/**
*
* # __fake_t_core__<T>
*
* fake type for register.
* if T "overptr", make type as ptr to limptr
*
*/
template <typename T>
struct __fake_t_core__ {
static constexpr bool overptr = sizeof(T) > sizeof(void*);
using type = typename limasptr<overptr, T>::type;
};
/**
*
* # fake_t<T>
*
* fake type for register.
*
* if cannot set T type as register, fake_t<T> is T*
* else, it T
*
*/
template <typename T>
using fake_t = typename __fake_t_core__<T>::type;
/**
*
* # is_overptr<T>
*
* overptr mean "size which over ptr size"
*
*/
template <typename T>
struct is_overptr {
static constexpr bool dose_it = __fake_t_core__<T>::overptr;
};
}
using __fake_t_space__::fake_t;
using __fake_t_space__::is_overptr;
/**
*
* # argv_t<T>
*
* argv type for fcal
*
* ## create
*
* create by constructor `argv_t<T>(T)`
*
* ## using
*
* `*argv_t<T>` to get T value
*
* ### etc
*
* - v : fake-type value
* - when v isptr : T* type that T type value's pointer
* - constexpr flag isptr : overptr flag of v
.* - faketype using : when overptr, faketype is pointer.
*
*/
template <typename T>
struct argv_t {
static constexpr bool isptr = is_overptr<T>::dose_it;
fake_t<T> v;
inline T operator*(void) {
if constexpr (isptr) return *v; //when v isptr, v is T type ponting pointer
else return v;
}
inline argv_t(T x) {
if constexpr (isptr) v = &x; //&x is ptr of x and when v isptr, v is pointer of x
else v = x;
}
};
}
/**
*
* # StackInterface
*
* - `::type_of_it` type attribute : this auto& field which usible in non-objects attribute
* - `::default_obj` type attribute : default construct obj
* - static method `::push<T>` : obj default pusher (actually, stack interface's cls obj is just like-inline functor, so it can make usible without obj)
* - virtual method `.instack_logic` : logic before stack var is pop
*
* ## actaully...
* umm... basically, it's prefer that mechanism which stackbyReveratedCallStackInterface style stack.
* 1. set (push)
* 2. `---- user work ----`
* 3. get (pop)
*
*/
typedef struct {
using type_of_it = this auto&;
using default_obj = type_of_it();
template <typename T, type_of_it obj = default_obj>
static inline T push(T x) {
return obj->push<T>(x);
}
template <typename T>
virtual inline T push(T) = 0;
virtual inline void instack_logic(void*) = 0;
} StackInterface; //well...
/**
*
* # stackbyReveratedCall"StackInterface"
*
* using call, using call stack as stack
*
* ## about
*
* using function call's local variable which placed in stack to use stack.
*
* 1. call with var
* 2. set (push)
* 3. `---- user work ----`
* 4. get (pop)
* 5. ret
*
*/
typedef struct : StackInterface {
template <typename T, typename V = __argv_t_space__::argv_t<T>>
using G = V;
template <typename T, typename G_t = G<T>>
inline T push(T register_v) override {
return *(this->push<T>(G_t(register_v)));
}
template <typename T, typename G_t = G<T>>
fcal G_t push(G_t register_v) override {
//push
T stack_local = *register_v;
//work
instack_logic((void*) register_v)
//pop
register_v = G_t(stack_local); //mov must
return register_v; //ret
}
} stackbyReveratedCallStackInterface;
/**
*
* # Heap"StackInterface"
*
* Stack in heap ({must inhurit as it... (even that fact that .... actually no error that you use it fu*king idi*tly... so plz 😭😭))
*/
typedef struct : StackInterface {} HeapStackInterface;
#endif