OR-Tools  9.6
source_location.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 // API for capturing source-code location information.
15 // Based on http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4519.pdf.
16 //
17 // To define a function that has access to the source location of the
18 // callsite, define it with a parameter of type `absl::SourceLocation`. The
19 // caller can then invoke the function, passing `ABSL_LOC` as the argument.
20 //
21 // If at all possible, make the `absl::SourceLocation` parameter be the
22 // function's last parameter. That way, when `std::source_location` is
23 // available, you will be able to switch to it, and give the parameter a default
24 // argument of `std::source_location::current()`. Users will then be able to
25 // omit that argument, and the default will automatically capture the location
26 // of the callsite.
27 
28 #ifndef OR_TOOLS_BASE_SOURCE_LOCATION_H_
29 #define OR_TOOLS_BASE_SOURCE_LOCATION_H_
30 
31 #include <cstdint>
32 
33 #include "absl/base/config.h"
34 
35 namespace absl {
36 
37 // Class representing a specific location in the source code of a program.
38 // `absl::SourceLocation` is copyable.
40  struct PrivateTag {
41  private:
42  explicit PrivateTag() = default;
43  friend class SourceLocation;
44  };
45 
46  public:
47  // Avoid this constructor; it populates the object with dummy values.
48  constexpr SourceLocation() : line_(0), file_name_(nullptr) {}
49 
50  // Wrapper to invoke the private constructor below. This should only be used
51  // by the `ABSL_LOC` macro, hence the name.
52  static constexpr SourceLocation DoNotInvokeDirectly(std::uint_least32_t line,
53  const char* file_name) {
54  return SourceLocation(line, file_name);
55  }
56 
57 #ifdef ABSL_HAVE_SOURCE_LOCATION_CURRENT
58  // SourceLocation::current
59  //
60  // Creates a `SourceLocation` based on the current line and file. APIs that
61  // accept a `SourceLocation` as a default parameter can use this to capture
62  // their caller's locations.
63  //
64  // Example:
65  //
66  // void TracedAdd(int i, SourceLocation loc = SourceLocation::current()) {
67  // std::cout << loc.file_name() << ":" << loc.line() << " added " << i;
68  // ...
69  // }
70  //
71  // void UserCode() {
72  // TracedAdd(1);
73  // TracedAdd(2);
74  // }
75  static constexpr SourceLocation current(
76  PrivateTag = PrivateTag{}, std::uint_least32_t line = __builtin_LINE(),
77  const char* file_name = __builtin_FILE()) {
78  return SourceLocation(line, file_name);
79  }
80 #else
81  // Creates a dummy `SourceLocation` of "<source_location>" at line number 1,
82  // if no `SourceLocation::current()` implementation is available.
83  static constexpr SourceLocation current() {
84  return SourceLocation(1, "<source_location>");
85  }
86 #endif
87  // The line number of the captured source location.
88  constexpr std::uint_least32_t line() const { return line_; }
89 
90  // The file name of the captured source location.
91  constexpr const char* file_name() const { return file_name_; }
92 
93  // `column()` and `function_name()` are omitted because we don't have a way to
94  // support them.
95 
96  private:
97  // Do not invoke this constructor directly. Instead, use the `ABSL_LOC` macro
98  // below.
99  //
100  // `file_name` must outlive all copies of the `absl::SourceLocation` object,
101  // so in practice it should be a string literal.
102  constexpr SourceLocation(std::uint_least32_t line, const char* file_name)
103  : line_(line), file_name_(file_name) {}
104 
105  friend constexpr int UseUnused() {
106  static_assert(SourceLocation(0, nullptr).unused_column_ == 0,
107  "Use the otherwise-unused member.");
108  return 0;
109  }
110 
111  // "unused" members are present to minimize future changes in the size of this
112  // type.
113  std::uint_least32_t line_;
114  std::uint_least32_t unused_column_ = 0;
115  const char* file_name_;
116 };
117 
118 } // namespace absl
119 
120 // If a function takes an `absl::SourceLocation` parameter, pass this as the
121 // argument.
122 #define ABSL_LOC ::absl::SourceLocation::DoNotInvokeDirectly(__LINE__, __FILE__)
123 
124 // ABSL_LOC_CURRENT_DEFAULT_ARG
125 //
126 // Specifies that a function should use `absl::SourceLocation::current()` on
127 // platforms where it will return useful information, but require explicitly
128 // passing `ABSL_LOC` on platforms where it would return dummy information.
129 //
130 // Usage:
131 //
132 // void MyLog(absl::string_view msg,
133 // absl::SourceLocation loc ABSL_LOC_CURRENT_DEFAULT_ARG) {
134 // std::cout << loc.file_name() << "@" << loc.line() << ": " << msg;
135 // }
136 //
137 #if ABSL_HAVE_SOURCE_LOCATION_CURRENT
138 #define ABSL_LOC_CURRENT_DEFAULT_ARG = ::absl::SourceLocation::current()
139 #else
140 #define ABSL_LOC_CURRENT_DEFAULT_ARG
141 #endif
142 
143 #endif // OR_TOOLS_BASE_SOURCE_LOCATION_H_
static constexpr SourceLocation current()
constexpr std::uint_least32_t line() const
constexpr const char * file_name() const
static constexpr SourceLocation DoNotInvokeDirectly(std::uint_least32_t line, const char *file_name)
constexpr SourceLocation()
constexpr friend int UseUnused()
Definition: cleanup.h:22