Skip to content

Latest commit

 

History

History
256 lines (215 loc) · 5.43 KB

295.md

File metadata and controls

256 lines (215 loc) · 5.43 KB
Info

Example

#include <stacktrace>
#include <iostream>

int foo() {
  std::cout << std::stacktrace::current();
  return {};
}

int main() {
  return foo();
}
0# foo()  at /app/example.cpp:5
1# main() at /app/example.cpp:10

https://godbolt.org/z/dd9x7Mejc

Puzzle

  • Can you implement call function which will call itself recursively N times and then it wil go through the stack and count how many calls has happend until the call at given source line (from)?
#include <stacktrace>

template<auto N>
[[nodiscard]] auto call(auto from);

int main() {
    using namespace boost::ut;

    "stacktrace"_test = [] {
        expect(1_u == call<0>(__LINE__));
        expect(3_u == call<2>(__LINE__));
        expect(4_u == call<3>(__LINE__));
    };
}

https://godbolt.org/z/rhE8EKf73

Solutions

template <auto N> 
[[nodiscard]] auto call(auto from) 
{
   if constexpr (N == 0)
   {
       return 1;
   }
   else
   {
       return call<N-1>(from) + 1;
   }
}

https://godbolt.org/z/jsdPaP6Px

template <auto N> 
[[nodiscard]] auto call(auto from) 
{
    if constexpr (N > 0)
    {
        return call<N-1>(from) + 1;
    }
    else
    {
        const auto st = std::stacktrace::current();
        return std::ranges::any_of(st, [from](const auto & s) {
            return from == s.source_line();
        });
    }
}

https://godbolt.org/z/hzj3nd36o

template <auto N>
[[nodiscard]] auto call(auto from) {
  if constexpr (N == 0) {
    const auto st = std::stacktrace::current();
    const auto it = std::find_if(std::begin(st), std::end(st),
        [&] (const auto& entry) { return entry.source_line() == from; });
    return std::distance(std::begin(st), it);
  } else {
    return call<N-1>(from);
  }
}

https://godbolt.org/z/EdTT115es

template<auto N>
[[nodiscard]] auto call(auto from) {
    if constexpr(N > 0) {
        return call<N-1>(from);
    }

    auto st = std::stacktrace::current();
    const auto first_empty = std::find_if(st.begin(), st.end(), [](auto&& trace) {
        return trace.description().empty();
    });
    return std::distance(st.begin(), first_empty);
}

https://godbolt.org/z/aG1n9j4ba

template<auto N>
[[nodiscard]] auto call(auto from)
{
    if constexpr(N ==0)
    {
        auto bt = std::stacktrace::current();
        return std::distance ( bt.begin()
                             , std::find_if( bt.begin()
                                           , bt.end()
                                           , [from](auto&& entry){ return entry.source_line() == from;}
                                           )

                             );
    } else
        return call<N-1>(from);
}

https://godbolt.org/z/v9nY35PK5

template <auto N>
[[nodiscard]] auto call(auto from) {
  if constexpr (N == 0) {
    const auto &st = std::stacktrace::current();
    const auto it = std::find_if(
        std::cbegin(st), std::cend(st),
        [=](const auto &entry) { return entry.source_line() == from; });
    return std::distance(std::cbegin(st), it);
  } else {
    return call<N - 1>(from);
  }
}

https://godbolt.org/z/hx9KbPTvr

template<auto N>
[[nodiscard]] auto call(auto from){
    if constexpr(N == 0){
        const auto& stacktrace = std::stacktrace::current();
        const auto it = std::ranges::find_if(stacktrace,
                        [from](const auto& entry){ return entry.source_line() == from; });

        return std::distance(std::cbegin(stacktrace), it);
    }
    else{
        return call<N-1>(from);
    }
}

https://godbolt.org/z/MfPGMc4xv

template<auto N>
[[nodiscard]] auto call(auto from) {
    if constexpr (N == 0) {
        const auto& st = std::stacktrace::current();
        auto last = std::find_if(st.begin(), st.end(), [from](auto&& it){
            return it.source_line() == from;
        });
        return std::distance(st.begin(), last);
    }
    else {
        return call<N - 1>(from);
    }
};

https://godbolt.org/z/9x84cfY4h

template<auto N>
[[nodiscard]] auto call(auto from) requires (N>=0) {
    if constexpr (N == 0)
    {
        auto cnt = 0;
        for( auto frame : std::stacktrace::current() )
        {
            if (to_string(frame).contains(__FUNCTION__)) {
                cnt++;
            }
        }
        return cnt;
    }
    else
    {
        return call<N-1>(from);
    }
};

https://godbolt.org/z/nfKda9oGr

template<auto N>
[[nodiscard]] auto call(auto from) {
    if constexpr(N>0)
        return call<N-1>(from);
    else {
        int n = 0;
        std::basic_stacktrace st = std::stacktrace::current();
        for(auto it = st.begin(); it < st.end(); it++)
            if (it->description().starts_with("auto call"))
                n++;
        return n;
    }
}

https://godbolt.org/z/G61dhrYsr

template<auto N>
[[nodiscard]] auto call(auto from){
    if constexpr (N < 1){
        auto s = std::stacktrace().current();
        auto entry = std::find_if(s.begin(),s.end(), [from](auto e){ return e.source_line() == from;});
        return (entry-s.begin());
    }
    else{
        return call<N-1>(from);
    }
}

https://godbolt.org/z/oTWz4h6z4