Skip to content
This repository has been archived by the owner on Jun 27, 2023. It is now read-only.
/ magic Public archive

[Deprecated] Magic of modern c++. Run time type info, reflection, and other fantasic features.

License

Notifications You must be signed in to change notification settings

coyorkdow/magic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This Repo has been deprecated. I wrote these codes when I was just an undergraduate student. Some codes are written during the first few months when I left the university and started a full-time enginner life. That's all hapended in a half year. From the view of today, That time I was just a c++ newbie and wrote some naive codes. This repo has been archived, and right now (2023/06) I'm dedicated to design and develop a new c++ reflect and serialization lib.

magic

Fantasic magic of modern c++

This reposity is aimed to show the power of modern c++ features. All codes are compliant the standard of C++11. I would say sorry if you are a favor of C++14/C++17/C++20. LOL.

Usage can be found in main.cpp.

quick_power.h

Calculate the exponent in compile time with a time complexity of O(log n),

Example

static_assert(Power<2, 10, 998244353>::Calculate() == 1024, "");
static_assert(Power<3, 20, 998244353>::Calculate() == 492051342, "");

binary_search.h

Binary searching in compile time.

Example

constexpr int arr[] = {1, 2, 3, 4, 4, 5, 5, 5, 6, 7};

static_assert(BinarySearch<int>::LowerBound(arr, 4) == 3, "");
static_assert(BinarySearch<int>::UpperBound(arr, 4) == 5, "");

index_sequence.h

Generate a compile time integer sequence, as well as std::index_sequence in C++14.

Example

template<size_t... N>
void TestIndexSequence(IndexSequence<N...>) {
  static const size_t seq[] = {N...};
  for (auto each : seq) std::cout << each << ' ';
  std::cout << std::endl;
}

// print 0 1 2 3 4 5 6 7 8 9 
TestIndexSequence(MakeIndexSequence<10>());

tuple.h

A simple implementation of tuple, rely on index_sequence.h.

Example

Tuple<int, double, std::string> t(1, 1.2, "11.2");
assert(t.size() == 3);
assert(t.Get<0>() == 1);
assert(t.Get<1>() == 1.2);
assert(t.Get<2>() == "11.2");

t.Set<0>(15);
t.Set<1>(89.64);
t.Set<2>("string");
assert(t.Get<0>() == 15);
assert(t.Get<1>() == 89.64);
assert(t.Get<2>() == "string");

auto tt = MakeTuple(1, "1234", 8.8);

type_of.h

Get type info during runtime.

Example

std::vector<std::map<std::pair<volatile const int *, std::string>, uint64_t>> testv;
meta = &TypeInfo<decltype(testv)>::info;
assert(meta->name() == "std::vector<std::map<std::pair<const volatile int*,std::string>,unsigned long long>>");
assert(meta->id() == TypeEnum::STD_Vector);
assert(meta->first()->name() == "std::map<std::pair<const volatile int*,std::string>,unsigned long long>");
assert(meta->first()->id() == TypeEnum::STD_Map);

meta = meta->first();
assert(meta->first()->name() == "std::pair<const volatile int*,std::string>");
assert(meta->second()->name() == "unsigned long long");

meta = meta->first();
assert(meta->first()->name() == "const volatile int*");
assert(meta->second()->name() == "std::string");

assert(meta->first()->PointerLevels() == 1); // is pointer
meta = meta->first()->first();
assert(meta->IsConst() && meta->IsVolatile());
assert(meta->decay()->name() == "int");

reflection.h

A simple implementation of reflection, rely on tuple.h and name_of.h.

auto fields = GetAllFields(a);
for (size_t i = 0; i < fields.size(); i++) {
  auto typeinfo = fields.TypeOf(i);
  switch (typeinfo->id()) {
    case TypeEnum::Float:
      if (typeinfo->PointerLevels() == 0) {
        fields.Set(i, (float) 99);
      } else if (typeinfo->PointerLevels() == 1) {
        float *ptr = *reinterpret_cast<float **>(fields.PtrOf(i));
        *ptr = 100;
      }
      break;
    case TypeEnum::STD_Vector:
      switch (typeinfo->first()->id()) {
        case TypeEnum::Int:
          fields.Set(i, std::vector<int>{5, 6, 7, 8});
          break;
        case TypeEnum::Double:
          fields.Set(i, std::vector<double>{5.5, 6.6});
          break;
        default:;
      }
      break;
    case TypeEnum::STD_String:
      fields.Set(i, std::string("yet another string"));
      break;
    default:;
  }
}

About

[Deprecated] Magic of modern c++. Run time type info, reflection, and other fantasic features.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published