| // Copyright (C) 2020-2021 Free Software Foundation, Inc. |
| // |
| // This file is part of the GNU ISO C++ Library. This library is free |
| // software; you can redistribute it and/or modify it under the |
| // terms of the GNU General Public License as published by the |
| // Free Software Foundation; either version 3, or (at your option) |
| // any later version. |
| |
| // This library is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU General Public License for more details. |
| |
| // You should have received a copy of the GNU General Public License along |
| // with this library; see the file COPYING3. If not see |
| // <http://www.gnu.org/licenses/>. |
| |
| // Example from C++ Standard Working Draft N4842, November 2019 Mailing |
| // Adapted for testing. |
| |
| // { dg-options "-std=gnu++2a" } |
| // { dg-do compile { target c++2a } } |
| |
| #include <source_location> |
| #include <string_view> |
| |
| struct s { |
| std::source_location member = std::source_location::current(); |
| int other_member = 1; |
| |
| constexpr s(std::source_location loc = std::source_location::current()) |
| : member(loc) // values of member refer to calling function |
| { } |
| |
| constexpr s(int blather) : // values of member refer to this location |
| other_member(blather) |
| { } |
| }; |
| |
| constexpr std::source_location |
| f(std::source_location a = std::source_location::current()) |
| { return a; } |
| |
| constexpr auto |
| g() |
| { |
| struct srcloc_and_line |
| { |
| std::source_location sl; |
| unsigned line; |
| }; |
| |
| std::source_location c = std::source_location::current(); |
| return srcloc_and_line{ f(c), __LINE__ - 1 }; |
| } |
| |
| #include "srcloc.h" |
| |
| int main () |
| { |
| constexpr std::source_location main_sl = std::source_location::current(); |
| constexpr unsigned main_sl_line = __LINE__ - 1; |
| constexpr std::source_location f_arg_sl = f(main_sl); |
| constexpr unsigned f_arg_sl_line = main_sl_line; |
| constexpr std::source_location g_sl = g().sl; |
| constexpr unsigned g_sl_line = g().line; |
| constexpr std::source_location f_sl = f(); |
| constexpr unsigned f_sl_line = __LINE__ - 1; |
| constexpr std::source_location h_sl = h(); // defined in ./srcloc.h |
| constexpr s member_main_sl(main_sl); |
| constexpr s member_defaulted_sl(1); |
| constexpr s member_sl = s{}; |
| constexpr unsigned member_sl_line = __LINE__ - 1; |
| |
| using namespace std::string_view_literals; |
| |
| static_assert (std::source_location::current ().line () == __LINE__); |
| static_assert (std::source_location::current ().column () == 48); |
| |
| |
| constexpr std::string_view main_sl_fn_name(main_sl.function_name()); |
| constexpr std::string_view main_sl_fi_name(main_sl.file_name()); |
| static_assert(main_sl.line() == main_sl_line); |
| // opening paren of call |
| static_assert(main_sl.column() == 73); |
| static_assert(main_sl_fn_name.ends_with("main()"sv)); |
| static_assert(main_sl_fi_name.ends_with("consteval.cc"sv)); |
| |
| constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name()); |
| constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name()); |
| static_assert(f_arg_sl.line() == f_arg_sl_line); |
| // opening paren of call |
| static_assert(f_arg_sl.column() == 73); |
| static_assert(f_arg_sl_fn_name.ends_with("main()"sv)); |
| static_assert(f_arg_sl_fi_name.ends_with("consteval.cc"sv)); |
| |
| constexpr std::string_view g_sl_fn_name(g_sl.function_name()); |
| constexpr std::string_view g_sl_fi_name(g_sl.file_name()); |
| static_assert(g_sl.line() == g_sl_line); |
| static_assert(g_sl.column() == 57); // opening paren of call |
| static_assert(g_sl_fn_name.ends_with("g()"sv)); |
| static_assert(g_sl_fi_name.ends_with("consteval.cc"sv)); |
| |
| constexpr std::string_view h_sl_fn_name(h_sl.function_name()); |
| constexpr std::string_view h_sl_fi_name(h_sl.file_name()); |
| static_assert(h_sl.line() == 23); |
| static_assert(h_sl.column() == 57); // opening paren of call |
| static_assert(h_sl_fn_name.ends_with("h()"sv)); |
| static_assert(h_sl_fi_name.ends_with("srcloc.h"sv)); |
| |
| constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name()); |
| constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name()); |
| static_assert(member_main_sl.member.line() == main_sl_line); |
| static_assert(member_main_sl.member.column() == 73); |
| static_assert(member_main_sl_fn_name.ends_with("main()"sv)); |
| static_assert(member_main_sl_fi_name.ends_with("consteval.cc"sv)); |
| |
| constexpr std::string_view member_defaulted_sl_fi_name( |
| member_defaulted_sl.member.file_name()); |
| constexpr std::string_view member_defaulted_sl_fn_name( |
| member_defaulted_sl.member.function_name()); |
| static_assert(member_defaulted_sl.member.line() == 36); |
| // closing paren of constructor declaration |
| static_assert(member_defaulted_sl.member.column() == 25); |
| static_assert(member_defaulted_sl_fn_name.ends_with("s::s(int)"sv)); |
| static_assert(member_defaulted_sl_fi_name.ends_with("consteval.cc"sv)); |
| |
| constexpr std::string_view member_sl_fi_name( |
| member_sl.member.file_name()); |
| constexpr std::string_view member_sl_fn_name( |
| member_sl.member.function_name()); |
| static_assert(member_sl.member.line() == member_sl_line); |
| // closing brace/paren of constructor |
| static_assert(member_sl.member.column() == 29); |
| static_assert(member_sl_fn_name.starts_with("int main()"sv)); |
| static_assert(member_sl_fi_name.ends_with("consteval.cc"sv)); |
| |
| constexpr std::string_view f_sl_fi_name(f_sl.file_name()); |
| constexpr std::string_view f_sl_fn_name(f_sl.function_name()); |
| static_assert(f_sl.line() == f_sl_line); |
| // opening paren of call |
| static_assert(f_sl.column() == 42); |
| static_assert(f_sl_fn_name.ends_with("main()"sv)); |
| static_assert(f_sl_fi_name.ends_with("consteval.cc"sv)); |
| |
| return 0; |
| } |