Skip to content

Commit

Permalink
routing: export from google3
Browse files Browse the repository at this point in the history
  • Loading branch information
Mizux committed Oct 3, 2024
1 parent da1be19 commit 781a98a
Show file tree
Hide file tree
Showing 16 changed files with 599 additions and 149 deletions.
9 changes: 9 additions & 0 deletions ortools/base/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,15 @@ cc_library(
],
)

cc_library(
name = "proto_enum_utils",
hdrs = ["proto_enum_utils.h"],
deps = [
"@com_google_absl//absl/types:span",
"@com_google_protobuf//:protobuf",
],
)

cc_library(
name = "ptr_util",
hdrs = ["ptr_util.h"],
Expand Down
209 changes: 209 additions & 0 deletions ortools/base/proto_enum_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Copyright 2010-2024 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef OR_TOOLS_BASE_PROTO_ENUM_UTILS_H_
#define OR_TOOLS_BASE_PROTO_ENUM_UTILS_H_

// Provides utility functions that help with handling Protocol Buffer enums.
//
// Examples:
//
// A function to easily iterate over all defined values of an enum known at
// compile-time:
//
// for (Proto::Enum e : EnumerateEnumValues<Proto::Enum>()) {
// ...
// }
//

#include <iterator>
#include <type_traits>

#include "absl/types/span.h"
#include "google/protobuf/descriptor.pb.h"

namespace google::protobuf::contrib::utils {

using google::protobuf::GetEnumDescriptor;
using google::protobuf::RepeatedField;

template <typename E>
class ProtoEnumIterator;

template <typename E>
class EnumeratedProtoEnumView;

template <typename E>
bool operator==(const ProtoEnumIterator<E>& a, const ProtoEnumIterator<E>& b);

template <typename E>
bool operator!=(const ProtoEnumIterator<E>& a, const ProtoEnumIterator<E>& b);

// Generic Proto enum iterator.
template <typename E>
class ProtoEnumIterator {
public:
typedef E value_type;
typedef std::forward_iterator_tag iterator_category;
typedef int difference_type;
typedef E* pointer;
typedef E& reference;

ProtoEnumIterator() : current_(0) {}

ProtoEnumIterator(const ProtoEnumIterator& other)
: current_(other.current_) {}

ProtoEnumIterator& operator=(const ProtoEnumIterator& other) {
current_ = other.current_;
return *this;
}

ProtoEnumIterator operator++(int) {
ProtoEnumIterator other(*this);
++(*this);
return other;
}

ProtoEnumIterator& operator++() {
++current_;
return *this;
}

E operator*() const {
return static_cast<E>(GetEnumDescriptor<E>()->value(current_)->number());
}

private:
explicit ProtoEnumIterator(int current) : current_(current) {}

int current_;

// Only EnumeratedProtoEnumView can instantiate ProtoEnumIterator.
friend class EnumeratedProtoEnumView<E>;
friend bool operator==
<>(const ProtoEnumIterator<E>& a, const ProtoEnumIterator<E>& b);
friend bool operator!=
<>(const ProtoEnumIterator<E>& a, const ProtoEnumIterator<E>& b);
};

template <typename E>
bool operator==(const ProtoEnumIterator<E>& a, const ProtoEnumIterator<E>& b) {
return a.current_ == b.current_;
}

template <typename E>
bool operator!=(const ProtoEnumIterator<E>& a, const ProtoEnumIterator<E>& b) {
return a.current_ != b.current_;
}

template <typename E>
class EnumeratedProtoEnumView {
public:
typedef E value_type;
typedef ProtoEnumIterator<E> iterator;
iterator begin() const { return iterator(0); }
iterator end() const {
return iterator(GetEnumDescriptor<E>()->value_count());
}
};

// Returns an EnumeratedProtoEnumView that can be iterated over:
// for (Proto::Enum e : EnumerateEnumValues<Proto::Enum>()) {
// ...
// }
template <typename E>
EnumeratedProtoEnumView<E> EnumerateEnumValues() {
return EnumeratedProtoEnumView<E>();
}

// Returns a view that allows to iterate directly over the enum values
// in an enum repeated field, wrapping the repeated field with a type-safe
// iterator that provides access to the enum values.
//
// for (Enum enum :
// REPEATED_ENUM_ADAPTER(message, repeated_enum_field)) {
// ...
// }
//
// It provides greater safety than iterating over the enum directly, as the
// following will fail to type-check:
//
// .proto
// RightEnum enum = 5;
//
// client .cc
// for (WrongEnum e : REPEATED_ENUM_ADAPTER(proto, enum)) { <- Error: Cannot
// cast from
// RightEnum to
// WrongEnum
// }
//
// NOTE: As per http://shortn/_CYfjpruK6N, unrecognized enum values are treated
// differently between proto2 and proto3.
//
// For proto2, they are stripped out from the message when read, so all
// unrecognized enum values from the wire format will be skipped when iterating
// over the wrapper (this is the same behavior as iterating over the
// RepeatedField<int> directly).
//
// For proto3, they are left as-is, so unrecognized enum values from the wire
// format will still be returned when iterating over the wrapper (this is the
// same behavior as iterating over the RepeatedField<int> directly).
//
#define REPEATED_ENUM_ADAPTER(var, field) \
google::protobuf::contrib::utils::internal::RepeatedEnumView< \
decltype(var.field(0))>(var.field())

// ==== WARNING TO USERS ====
// Below are internal implementations, not public API, and may change without
// notice. Do NOT use directly.

namespace internal {

// Implementation for REPEATED_ENUM_ADAPTER. This does not provide type safety
// thus should be used through REPEATED_ENUM_ADAPTER only. See cr/246914845 for
// context.
template <typename E>
class RepeatedEnumView {
public:
class Iterator : public std::iterator<std::input_iterator_tag, E> {
public:
explicit Iterator(RepeatedField<int>::const_iterator ptr) : ptr_(ptr) {}
bool operator==(const Iterator& it) const { return ptr_ == it.ptr_; }
bool operator!=(const Iterator& it) const { return ptr_ != it.ptr_; }
Iterator& operator++() {
++ptr_;
return *this;
}
E operator*() const { return static_cast<E>(*ptr_); }

private:
RepeatedField<int>::const_iterator ptr_;
};

explicit RepeatedEnumView(const RepeatedField<int>& repeated_field)
: repeated_field_(repeated_field) {}

Iterator begin() const { return Iterator(repeated_field_.begin()); }
Iterator end() const { return Iterator(repeated_field_.end()); }

private:
const RepeatedField<int>& repeated_field_;
};

} // namespace internal

} // namespace google::protobuf::contrib::utils

#endif // OR_TOOLS_BASE_PROTO_ENUM_UTILS_H_
1 change: 1 addition & 0 deletions ortools/constraint_solver/constraint_solver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3280,6 +3280,7 @@ Decision* ProfiledDecisionBuilder::Next(Solver* const solver) {
Decision* const decision = db_->Next(solver);
timer_.Stop();
seconds_ += timer_.Get();
solver->set_context("");
return decision;
}

Expand Down
Loading

0 comments on commit 781a98a

Please sign in to comment.