mediapipe/mediapipe/util/sequence/media_sequence_util.h
MediaPipe Team 7c2d654d67 Convert CHECK macro to ABSL_CHECK.
Chrome can't use Absl's CHECK because of collisions with its own version.

PiperOrigin-RevId: 561740965
2023-08-31 13:20:29 -07:00

1190 lines
77 KiB
C++

// Copyright 2019 The MediaPipe Authors.
//
// 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.
// A set of lightweight functions and macros to simplify access to tensorflow
// SequenceExample features, and macros to create getters and setters for common
// types. In general, the definitions in media_sequence.h should be sufficient
// for most cases.
//
// Four low-level patterns can be stored in SequenceExamples:
// Single elements per sequence.
// Vector elements per sequence.
// Single elements per timestep.
// Vector elements per timestep.
//
// This utility enable creating functions for each pattern for each of the
// data types in SequenceExamples (bytes, floats, ints). Each macro takes a name
// to use in the code and a key to use in the SequenceExample. For each pattern
// the most basic function prototypes for the name='MyFeature' are similar to:
//
// {BYTES,INT64,FLOAT}_CONTEXT_FEATURE:
// string GetMyFeatureKey(sequence)
// bool HasMyFeature(sequence)
// void ClearMyFeature(*sequence)
// void SetMyFeature(value, *sequence)
// TYPE GetMyFeature(sequence)
//
// VECTOR_{BYTES,INT64,FLOAT}_CONTEXT_FEATURE:
// string GetMyFeatureKey(sequence)
// bool HasMyFeature(sequence)
// void ClearMyFeature(*sequence)
// void SetMyFeature(repeated_value, *sequence)
// void AddMyFeature(value, *sequence)
// int GetMyFeatureSize(sequence)
// Repeated<TYPE> GetMyFeature(sequence)
// TYPE GetMyFeatureAt(sequence)
//
// {BYTES,INT64,FLOAT}_FEATURE_LIST:
// string GetMyFeatureKey(sequence)
// bool HasMyFeature(sequence)
// void ClearMyFeature(*sequence)
// void AddMyFeature(value, *sequence)
// int GetMyFeatureSize(sequence)
// TYPE GetMyFeatureAt(sequence)
//
// VECTOR_{BYTES,INT64,FLOAT}_FEATURE_LIST:
// string GetMyFeatureKey(sequence)
// bool HasMyFeature(sequence)
// void ClearMyFeature(*sequence)
// void AddMyFeature(repeated_value, *sequence)
// int GetMyFeatureSize(sequence)
// Repeated<TYPE> GetMyFeatureAt(sequence)
//
// To see the exact types, please see the actual definitions, but this list
// should be sufficient for quick reference.
//
// Each function is also overloaded to accept a prefix for the key. E.g.
// HasMyFeature(sequence) takes a prefix HasMyFeature(prefix, sequence). In the
// sequence example, if the key was 'my_feature' then adding a prefix of
// 'PREFIX' results in the key 'PREFIX/my_feature'. Note that the / is added
// automatically between the prefix and the key. Prefixes are particularly
// useful when multiple types of data have similar or identical structure but
// are derived from different means. For example, stereo images could be encoded
// AddImageEncoded("LEFT", left_encoded_image_string, &sequence); and
// AddImageEncdedd("RIGHT", right_encoded_image_string, &sequence);.
//
// To avoid needing to repeatedly specify prefixes, prefixes can be baked into
// the functions with a new name. Calling a macro starting with
// FIXED_PREFIX_...(name, key, prefix) will create the same API as the version
// without a prefix, but the prefix will be used for all calls. Calling one
// of the created functions with a new prefix replaces the fixed prefix and does
// not prepend it. Using the example above,
// FIXED_PREFIX_BYTES_FEATURE_LIST(LeftImageEncoded, 'image/encoded', 'LEFT')
// allows calls to AddLeftImageEncoded(left_encoded_image_string, &sequence) and
// AddImageEncoded("LEFT", left_encoded_image_string, &sequence) to have the
// same effect of adding data to 'LEFT/image/encoded'.
#ifndef MEDIAPIPE_TENSORFLOW_SEQUENCE_MEDIA_SEQUENCE_UTIL_H_
#define MEDIAPIPE_TENSORFLOW_SEQUENCE_MEDIA_SEQUENCE_UTIL_H_
#include <algorithm>
#include <string>
#include <vector>
#include "absl/log/absl_check.h"
#include "mediapipe/framework/port/integral_types.h"
#include "mediapipe/framework/port/logging.h"
#include "mediapipe/framework/port/proto_ns.h"
#include "tensorflow/core/example/example.pb.h"
#include "tensorflow/core/example/feature.pb.h"
namespace mediapipe {
namespace mediasequence {
// Returns true if the key is in the sequence's context.
inline const bool HasContext(const tensorflow::SequenceExample& sequence,
const std::string& key) {
return (sequence.context().feature().find(key) !=
sequence.context().feature().end());
}
inline const std::string merge_prefix(const std::string& prefix,
const std::string& key) {
if (prefix.empty()) {
return key;
} else {
return prefix + "/" + key;
}
}
// Returns a refrerence to the feature in context with the provided key, which
// must exist.
inline const tensorflow::Feature& GetContext(
const tensorflow::SequenceExample& sequence, const std::string& key) {
// proto map's at function also checks whether key is present, but it doesn't
// print the missing key when it check-fails.
const auto it = sequence.context().feature().find(key);
ABSL_CHECK(it != sequence.context().feature().end())
<< "Could not find context key " << key << ". Sequence: \n"
<< sequence.DebugString();
return it->second;
}
// Returns a pointer to the feature in context with the provided key, inserting
// it if necessary.
inline tensorflow::Feature* MutableContext(
const std::string& key, tensorflow::SequenceExample* sequence) {
return &((*sequence->mutable_context()->mutable_feature())[key]);
}
// Clears the context key specified then adds a new value.
inline void SetContextFloat(const std::string& key, float value,
tensorflow::SequenceExample* sequence) {
MutableContext(key, sequence)->mutable_float_list()->clear_value();
MutableContext(key, sequence)->mutable_float_list()->add_value(value);
}
inline void SetContextInt64(const std::string& key, int64 value,
tensorflow::SequenceExample* sequence) {
MutableContext(key, sequence)->mutable_int64_list()->clear_value();
MutableContext(key, sequence)->mutable_int64_list()->add_value(value);
}
inline void SetContextBytes(const std::string& key, const std::string& value,
tensorflow::SequenceExample* sequence) {
MutableContext(key, sequence)->mutable_bytes_list()->clear_value();
MutableContext(key, sequence)->mutable_bytes_list()->add_value(value);
}
template <typename TContainer>
void SetContextFloatList(const std::string& key, const TContainer& values,
tensorflow::SequenceExample* sequence) {
MutableContext(key, sequence)->mutable_float_list()->clear_value();
for (auto value : values) {
MutableContext(key, sequence)->mutable_float_list()->add_value(value);
}
}
template <typename TContainer>
void SetContextInt64List(const std::string& key, const TContainer& values,
tensorflow::SequenceExample* sequence) {
MutableContext(key, sequence)->mutable_int64_list()->clear_value();
for (auto value : values) {
MutableContext(key, sequence)->mutable_int64_list()->add_value(value);
}
}
template <typename TContainer>
void SetContextBytesList(const std::string& key, const TContainer& values,
tensorflow::SequenceExample* sequence) {
MutableContext(key, sequence)->mutable_bytes_list()->clear_value();
for (const auto& value : values) {
MutableContext(key, sequence)->mutable_bytes_list()->add_value(value);
}
}
// Returns true if the key is in the sequence's FeatureLists.
inline const bool HasFeatureList(const tensorflow::SequenceExample& sequence,
const std::string& key) {
return (sequence.feature_lists().feature_list().find(key) !=
sequence.feature_lists().feature_list().end());
}
// Returns a refrerence to the feature list with the provided key, which must
// exist.
inline const tensorflow::FeatureList& GetFeatureList(
const tensorflow::SequenceExample& sequence, const std::string& key) {
return sequence.feature_lists().feature_list().at(key);
}
// Returns a pointer to the feature list with the provided key, inserting
// it if necessary.
inline tensorflow::FeatureList* MutableFeatureList(
const std::string& key, tensorflow::SequenceExample* sequence) {
return &((*sequence->mutable_feature_lists()->mutable_feature_list())[key]);
}
// Returns the size of the FeatureList or 0 if the feature list is not present.
inline const int GetFeatureListSize(const tensorflow::SequenceExample& sequence,
const std::string& key) {
if (HasFeatureList(sequence, key)) {
return GetFeatureList(sequence, key).feature_size();
} else {
return 0;
}
}
// Returns a refrerence to the float values for the feature list indicated by
// key at the provided sequence index.
inline const proto_ns::RepeatedField<float>& GetFloatsAt(
const tensorflow::SequenceExample& sequence, const std::string& key,
const int index) {
const tensorflow::FeatureList& fl = GetFeatureList(sequence, key);
ABSL_CHECK_LT(index, fl.feature_size())
<< "Sequence: \n " << sequence.DebugString();
return fl.feature().Get(index).float_list().value();
}
// Returns a refrerence to the int64 values for the feature list indicated by
// key at the provided sequence index.
inline const proto_ns::RepeatedField<int64>& GetInt64sAt(
const tensorflow::SequenceExample& sequence, const std::string& key,
const int index) {
const tensorflow::FeatureList& fl = GetFeatureList(sequence, key);
ABSL_CHECK_LT(index, fl.feature_size())
<< "Sequence: \n " << sequence.DebugString();
return fl.feature().Get(index).int64_list().value();
}
// Returns a refrerence to the string values for the feature list indicated by
// key at the provided sequence index.
inline const proto_ns::RepeatedPtrField<std::string>& GetBytesAt(
const tensorflow::SequenceExample& sequence, const std::string& key,
const int index) {
const tensorflow::FeatureList& fl = GetFeatureList(sequence, key);
ABSL_CHECK_LT(index, fl.feature_size())
<< "Sequence: \n " << sequence.DebugString();
return fl.feature().Get(index).bytes_list().value();
}
// Adds any iterable (with begin and end) to a FeatureList as a float Feature.
template <typename TContainer>
void AddFloatContainer(const std::string& key, const TContainer& float_list,
tensorflow::SequenceExample* sequence) {
auto* feature = MutableFeatureList(key, sequence)->add_feature();
std::copy(float_list.begin(), float_list.end(),
proto_ns::RepeatedFieldBackInserter(
feature->mutable_float_list()->mutable_value()));
}
// Adds any iterable (with begin and end) to a FeatureList as a int64 Feature.
template <typename TContainer>
void AddInt64Container(const std::string& key, const TContainer& int64_list,
tensorflow::SequenceExample* sequence) {
auto* feature = MutableFeatureList(key, sequence)->add_feature();
std::copy(int64_list.begin(), int64_list.end(),
proto_ns::RepeatedFieldBackInserter(
feature->mutable_int64_list()->mutable_value()));
}
// Adds any iterable (with begin and end) to a FeatureList as a bytes Feature.
template <typename TContainer>
void AddBytesContainer(const std::string& key, const TContainer& bytes_list,
tensorflow::SequenceExample* sequence) {
auto* feature = MutableFeatureList(key, sequence)->add_feature();
std::copy(bytes_list.begin(), bytes_list.end(),
proto_ns::RepeatedPtrFieldBackInserter(
feature->mutable_bytes_list()->mutable_value()));
}
// The macros provided below are useful for creating getters and setters for
// keys and values in a tf::SequenceExample. You only need to specify the C++
// name to use in the functions and the string key used in the SequenceExample
// proto maps. Macro versions exist for {strings, int64s, and floats} for
// creating singular or repeated context features and singular or repeated
// feature_list features.
// Helpers to create functions names in the macros below.
#define CONCAT_STR2(a, b) a##b
#define CONCAT_STR3(a, b, c) a##b##c
// This macro creates functions for HasX, GetX, ClearX, and SetX where X is a
// name and the value stored is a string in the context.
#define PREFIXED_BYTES_CONTEXT_FEATURE(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasContext(sequence, merge_prefix(prefix, key)); \
} \
inline const std::string& CONCAT_STR2(Get, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.bytes_list() \
.value(0); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_context()->mutable_feature()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Set, name)(const std::string& prefix, \
const std::string& value, \
tensorflow::SequenceExample* sequence) { \
SetContextBytes(merge_prefix(prefix, key), value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_BYTES_CONTEXT_FEATURE(name, key, prefix) \
PREFIXED_BYTES_CONTEXT_FEATURE(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const std::string& CONCAT_STR2( \
Get, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Get, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Set, name)(const std::string& value, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Set, name)(prefix, value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define BYTES_CONTEXT_FEATURE(name, key) \
FIXED_PREFIX_BYTES_CONTEXT_FEATURE(name, key, "")
// This macro creates functions for HasX, GetX, ClearX, and SetX where X is a
// name and the value stored is a int64 in the context.
#define PREFIXED_INT64_CONTEXT_FEATURE(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasContext(sequence, merge_prefix(prefix, key)); \
} \
inline const int64 CONCAT_STR2(Get, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.int64_list() \
.value(0); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_context()->mutable_feature()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Set, name)(const std::string& prefix, \
const int64& value, \
tensorflow::SequenceExample* sequence) { \
SetContextInt64(merge_prefix(prefix, key), value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_INT64_CONTEXT_FEATURE(name, key, prefix) \
PREFIXED_INT64_CONTEXT_FEATURE(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int64 CONCAT_STR2( \
Get, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Get, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Set, name)(const int64& value, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Set, name)(prefix, value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define INT64_CONTEXT_FEATURE(name, key) \
FIXED_PREFIX_INT64_CONTEXT_FEATURE(name, key, "");
// This macro creates functions for HasX, GetX, ClearX, and SetX where X is a
// name and the value stored is a float in the context.
#define PREFIXED_FLOAT_CONTEXT_FEATURE(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasContext(sequence, merge_prefix(prefix, key)); \
} \
inline const float CONCAT_STR2(Get, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.float_list() \
.value(0); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_context()->mutable_feature()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Set, name)(const std::string& prefix, \
const float& value, \
tensorflow::SequenceExample* sequence) { \
SetContextFloat(merge_prefix(prefix, key), value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_FLOAT_CONTEXT_FEATURE(name, key, prefix) \
PREFIXED_FLOAT_CONTEXT_FEATURE(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const float CONCAT_STR2( \
Get, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Get, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Set, name)(const float& value, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Set, name)(prefix, value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define FLOAT_CONTEXT_FEATURE(name, key) \
FIXED_PREFIX_FLOAT_CONTEXT_FEATURE(name, key, "")
// This macro creates functions for HasX, GetX, ClearX, SetX, GetXSize, GetXAt,
// and AddX where X is a name and the value stored is a sequence of strings in
// the context.
#define PREFIXED_VECTOR_BYTES_CONTEXT_FEATURE(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasContext(sequence, merge_prefix(prefix, key)); \
} \
inline const int CONCAT_STR3(Get, name, Size)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
if (CONCAT_STR2(Has, name)(prefix, sequence)) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.bytes_list() \
.value_size(); \
} else { \
return 0; \
} \
} \
inline const proto_ns::RepeatedPtrField<std::string>& CONCAT_STR2( \
Get, name)(const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.bytes_list() \
.value(); \
} \
inline const std::string& CONCAT_STR3(Get, name, At)( \
const std::string& prefix, const tensorflow::SequenceExample& sequence, \
int i) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.bytes_list() \
.value(i); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_context()->mutable_feature()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Set, name)(const std::string& prefix, \
const ::std::vector<std::string>& values, \
tensorflow::SequenceExample* sequence) { \
SetContextBytesList(merge_prefix(prefix, key), values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Set, name)(const std::string& prefix, \
const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
SetContextBytesList(merge_prefix(prefix, key), values, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const std::string& value, \
tensorflow::SequenceExample* sequence) { \
MutableContext(merge_prefix(prefix, key), sequence) \
->mutable_bytes_list() \
->add_value(value); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_VECTOR_BYTES_CONTEXT_FEATURE(name, key, prefix) \
PREFIXED_VECTOR_BYTES_CONTEXT_FEATURE(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int CONCAT_STR3( \
Get, name, Size)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR3(Get, name, Size)(prefix, sequence); \
} \
inline const proto_ns::RepeatedPtrField<std::string>& CONCAT_STR2( \
Get, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Get, name)(prefix, sequence); \
} \
inline const std::string& CONCAT_STR3(Get, name, At)( \
const tensorflow::SequenceExample& sequence, int i) { \
return CONCAT_STR3(Get, name, At)(prefix, sequence, i); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Set, name)(const ::std::vector<std::string>& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Set, name)(prefix, values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Set, name)(const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Set, name)(prefix, values, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& value, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define VECTOR_BYTES_CONTEXT_FEATURE(name, key) \
FIXED_PREFIX_VECTOR_BYTES_CONTEXT_FEATURE(name, key, "");
// This macro creates functions for HasX, GetX, ClearX, SetX, GetXAt, and AddX
// where X is a name and the value stored is a sequence of int64s in the
// context.
#define PREFIXED_VECTOR_INT64_CONTEXT_FEATURE(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasContext(sequence, merge_prefix(prefix, key)); \
} \
inline const int CONCAT_STR3(Get, name, Size)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
if (CONCAT_STR2(Has, name)(prefix, sequence)) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.int64_list() \
.value_size(); \
} else { \
return 0; \
} \
} \
inline const proto_ns::RepeatedField<int64>& CONCAT_STR2(Get, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.int64_list() \
.value(); \
} \
inline const int64 CONCAT_STR3(Get, name, At)( \
const std::string& prefix, const tensorflow::SequenceExample& sequence, \
int i) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.int64_list() \
.value(i); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_context()->mutable_feature()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Set, name)(const std::string& prefix, \
const ::std::vector<int64>& values, \
tensorflow::SequenceExample* sequence) { \
SetContextInt64List(merge_prefix(prefix, key), values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Set, name)(const std::string& prefix, \
const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
SetContextInt64List(merge_prefix(prefix, key), values, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const int64& value, \
tensorflow::SequenceExample* sequence) { \
MutableContext(merge_prefix(prefix, key), sequence) \
->mutable_int64_list() \
->add_value(value); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_VECTOR_INT64_CONTEXT_FEATURE(name, key, prefix) \
PREFIXED_VECTOR_INT64_CONTEXT_FEATURE(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int CONCAT_STR3( \
Get, name, Size)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR3(Get, name, Size)(prefix, sequence); \
} \
inline const proto_ns::RepeatedField<int64>& CONCAT_STR2( \
Get, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Get, name)(prefix, sequence); \
} \
inline const int64 CONCAT_STR3(Get, name, At)( \
const tensorflow::SequenceExample& sequence, int i) { \
return CONCAT_STR3(Get, name, At)(prefix, sequence, i); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Set, name)(const ::std::vector<int64>& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Set, name)(prefix, values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Set, name)(const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Set, name)(prefix, values, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const int64& value, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define VECTOR_INT64_CONTEXT_FEATURE(name, key) \
FIXED_PREFIX_VECTOR_INT64_CONTEXT_FEATURE(name, key, "");
// This macro creates functions for HasX, GetX, ClearX, SetX, GetXAt, and AddX
// where X is a name and the value stored is a sequence of floats in the
// context.
#define PREFIXED_VECTOR_FLOAT_CONTEXT_FEATURE(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasContext(sequence, merge_prefix(prefix, key)); \
} \
inline const int CONCAT_STR3(Get, name, Size)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
if (CONCAT_STR2(Has, name)(prefix, sequence)) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.float_list() \
.value_size(); \
} else { \
return 0; \
} \
} \
inline const proto_ns::RepeatedField<float>& CONCAT_STR2(Get, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.float_list() \
.value(); \
} \
inline const float CONCAT_STR3(Get, name, At)( \
const std::string& prefix, const tensorflow::SequenceExample& sequence, \
int i) { \
return GetContext(sequence, merge_prefix(prefix, key)) \
.float_list() \
.value(i); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_context()->mutable_feature()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Set, name)(const std::string& prefix, \
const ::std::vector<float>& values, \
tensorflow::SequenceExample* sequence) { \
SetContextFloatList(merge_prefix(prefix, key), values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Set, name)(const std::string& prefix, \
const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
SetContextFloatList(merge_prefix(prefix, key), values, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const float& value, \
tensorflow::SequenceExample* sequence) { \
MutableContext(merge_prefix(prefix, key), sequence) \
->mutable_float_list() \
->add_value(value); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_VECTOR_FLOAT_CONTEXT_FEATURE(name, key, prefix) \
PREFIXED_VECTOR_FLOAT_CONTEXT_FEATURE(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int CONCAT_STR3( \
Get, name, Size)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR3(Get, name, Size)(prefix, sequence); \
} \
inline const proto_ns::RepeatedField<float>& CONCAT_STR2( \
Get, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Get, name)(prefix, sequence); \
} \
inline const float CONCAT_STR3(Get, name, At)( \
const tensorflow::SequenceExample& sequence, int i) { \
return CONCAT_STR3(Get, name, At)(prefix, sequence, i); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Set, name)(const ::std::vector<float>& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Set, name)(prefix, values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Set, name)(const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Set, name)(prefix, values, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const float& value, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define VECTOR_FLOAT_CONTEXT_FEATURE(name, key) \
FIXED_PREFIX_VECTOR_FLOAT_CONTEXT_FEATURE(name, key, "");
// This macro creates functions for HasX, GetXSize, GetXAt, ClearX, and AddX
// where X is a name and the value stored is a string in a feature_list.
#define PREFIXED_BYTES_FEATURE_LIST(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasFeatureList(sequence, merge_prefix(prefix, key)); \
} \
inline const int CONCAT_STR3(Get, name, Size)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetFeatureListSize(sequence, merge_prefix(prefix, key)); \
} \
inline const std::string& CONCAT_STR3(Get, name, At)( \
const std::string& prefix, const tensorflow::SequenceExample& sequence, \
int index) { \
return GetBytesAt(sequence, merge_prefix(prefix, key), index).Get(0); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_feature_lists()->mutable_feature_list()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const std::string& value, \
tensorflow::SequenceExample* sequence) { \
MutableFeatureList(merge_prefix(prefix, key), sequence) \
->add_feature() \
->mutable_bytes_list() \
->add_value(value); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_BYTES_FEATURE_LIST(name, key, prefix) \
PREFIXED_BYTES_FEATURE_LIST(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int CONCAT_STR3( \
Get, name, Size)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR3(Get, name, Size)(prefix, sequence); \
} \
inline const std::string& CONCAT_STR3(Get, name, At)( \
const tensorflow::SequenceExample& sequence, int index) { \
return CONCAT_STR3(Get, name, At)(prefix, sequence, index); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& value, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define BYTES_FEATURE_LIST(name, key) \
FIXED_PREFIX_BYTES_FEATURE_LIST(name, key, "");
// This macro creates functions for HasX, GetXSize, GetXAt, ClearX, and AddX
// where X is a name and the value stored is a int64 in a feature_list.
#define PREFIXED_INT64_FEATURE_LIST(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasFeatureList(sequence, merge_prefix(prefix, key)); \
} \
inline const int CONCAT_STR3(Get, name, Size)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetFeatureListSize(sequence, merge_prefix(prefix, key)); \
} \
inline const int64 CONCAT_STR3(Get, name, At)( \
const std::string& prefix, const tensorflow::SequenceExample& sequence, \
int index) { \
return GetInt64sAt(sequence, merge_prefix(prefix, key), index).Get(0); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_feature_lists()->mutable_feature_list()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const int64 value, \
tensorflow::SequenceExample* sequence) { \
MutableFeatureList(merge_prefix(prefix, key), sequence) \
->add_feature() \
->mutable_int64_list() \
->add_value(value); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_INT64_FEATURE_LIST(name, key, prefix) \
PREFIXED_INT64_FEATURE_LIST(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int CONCAT_STR3( \
Get, name, Size)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR3(Get, name, Size)(prefix, sequence); \
} \
inline const int64 CONCAT_STR3(Get, name, At)( \
const tensorflow::SequenceExample& sequence, int index) { \
return CONCAT_STR3(Get, name, At)(prefix, sequence, index); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const int64& value, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define INT64_FEATURE_LIST(name, key) \
FIXED_PREFIX_INT64_FEATURE_LIST(name, key, "");
// This macro creates functions for HasX, GetXSize, GetXAt, ClearX, and AddX
// where X is a name and the value stored is a float in a feature_list.
#define PREFIXED_FLOAT_FEATURE_LIST(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasFeatureList(sequence, merge_prefix(prefix, key)); \
} \
inline const int CONCAT_STR3(Get, name, Size)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetFeatureListSize(sequence, merge_prefix(prefix, key)); \
} \
inline const float CONCAT_STR3(Get, name, At)( \
const std::string& prefix, const tensorflow::SequenceExample& sequence, \
int index) { \
return GetFloatsAt(sequence, merge_prefix(prefix, key), index).Get(0); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_feature_lists()->mutable_feature_list()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const float value, \
tensorflow::SequenceExample* sequence) { \
MutableFeatureList(merge_prefix(prefix, key), sequence) \
->add_feature() \
->mutable_float_list() \
->add_value(value); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_FLOAT_FEATURE_LIST(name, key, prefix) \
PREFIXED_FLOAT_FEATURE_LIST(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int CONCAT_STR3( \
Get, name, Size)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR3(Get, name, Size)(prefix, sequence); \
} \
inline const float CONCAT_STR3(Get, name, At)( \
const tensorflow::SequenceExample& sequence, int index) { \
return CONCAT_STR3(Get, name, At)(prefix, sequence, index); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const float& value, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, value, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define FLOAT_FEATURE_LIST(name, key) \
FIXED_PREFIX_FLOAT_FEATURE_LIST(name, key, "");
// This macro creates functions for HasX, GetXSize, GetXAt, ClearX, and AddX
// where X is a name and the value stored is a sequence of strings in a
// feature_list.
#define PREFIXED_VECTOR_BYTES_FEATURE_LIST(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasFeatureList(sequence, merge_prefix(prefix, key)); \
} \
inline const int CONCAT_STR3(Get, name, Size)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetFeatureListSize(sequence, merge_prefix(prefix, key)); \
} \
inline const proto_ns::RepeatedPtrField<std::string>& CONCAT_STR3( \
Get, name, At)(const std::string& prefix, \
const tensorflow::SequenceExample& sequence, int index) { \
return GetBytesAt(sequence, merge_prefix(prefix, key), index); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_feature_lists()->mutable_feature_list()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const ::std::vector<std::string>& values, \
tensorflow::SequenceExample* sequence) { \
AddBytesContainer(merge_prefix(prefix, key), values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
AddBytesContainer(merge_prefix(prefix, key), values, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_VECTOR_BYTES_FEATURE_LIST(name, key, prefix) \
PREFIXED_VECTOR_BYTES_FEATURE_LIST(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int CONCAT_STR3( \
Get, name, Size)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR3(Get, name, Size)(prefix, sequence); \
} \
inline const proto_ns::RepeatedPtrField<std::string>& CONCAT_STR3( \
Get, name, At)(const tensorflow::SequenceExample& sequence, int index) { \
return CONCAT_STR3(Get, name, At)(prefix, sequence, index); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const ::std::vector<std::string>& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Add, name)(const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, values, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define VECTOR_BYTES_FEATURE_LIST(name, key) \
FIXED_PREFIX_VECTOR_BYTES_FEATURE_LIST(name, key, "");
// This macro creates functions for HasX, GetXSize, GetXAt, ClearX, and AddX
// where X is a name and the value stored is a sequence of int64 in a
// feature_list.
#define PREFIXED_VECTOR_INT64_FEATURE_LIST(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasFeatureList(sequence, merge_prefix(prefix, key)); \
} \
inline const int CONCAT_STR3(Get, name, Size)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetFeatureListSize(sequence, merge_prefix(prefix, key)); \
} \
inline const proto_ns::RepeatedField<int64>& CONCAT_STR3(Get, name, At)( \
const std::string& prefix, const tensorflow::SequenceExample& sequence, \
int index) { \
return GetInt64sAt(sequence, merge_prefix(prefix, key), index); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_feature_lists()->mutable_feature_list()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const ::std::vector<int64>& values, \
tensorflow::SequenceExample* sequence) { \
AddInt64Container(merge_prefix(prefix, key), values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
AddInt64Container(merge_prefix(prefix, key), values, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_VECTOR_INT64_FEATURE_LIST(name, key, prefix) \
PREFIXED_VECTOR_INT64_FEATURE_LIST(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int CONCAT_STR3( \
Get, name, Size)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR3(Get, name, Size)(prefix, sequence); \
} \
inline const proto_ns::RepeatedField<int64>& CONCAT_STR3(Get, name, At)( \
const tensorflow::SequenceExample& sequence, int index) { \
return CONCAT_STR3(Get, name, At)(prefix, sequence, index); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const ::std::vector<int64>& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Add, name)(const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, values, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define VECTOR_INT64_FEATURE_LIST(name, key) \
FIXED_PREFIX_VECTOR_INT64_FEATURE_LIST(name, key, "");
// This macro creates functions for HasX, GetXSize, GetXAt, ClearX, and AddX
// where X is a name and the value stored is a sequence of floats in a
// feature_list.
#define PREFIXED_VECTOR_FLOAT_FEATURE_LIST(name, key) \
inline const bool CONCAT_STR2(Has, name)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return HasFeatureList(sequence, merge_prefix(prefix, key)); \
} \
inline const int CONCAT_STR3(Get, name, Size)( \
const std::string& prefix, \
const tensorflow::SequenceExample& sequence) { \
return GetFeatureListSize(sequence, merge_prefix(prefix, key)); \
} \
inline const proto_ns::RepeatedField<float>& CONCAT_STR3(Get, name, At)( \
const std::string& prefix, const tensorflow::SequenceExample& sequence, \
int index) { \
return GetFloatsAt(sequence, merge_prefix(prefix, key), index); \
} \
inline void CONCAT_STR2(Clear, name)( \
const std::string& prefix, tensorflow::SequenceExample* sequence) { \
sequence->mutable_feature_lists()->mutable_feature_list()->erase( \
merge_prefix(prefix, key)); \
} \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const ::std::vector<float>& values, \
tensorflow::SequenceExample* sequence) { \
AddFloatContainer(merge_prefix(prefix, key), values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Add, name)(const std::string& prefix, \
const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
AddFloatContainer(merge_prefix(prefix, key), values, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, \
Key)(const std::string& prefix) { \
return merge_prefix(prefix, key); \
}
#define FIXED_PREFIX_VECTOR_FLOAT_FEATURE_LIST(name, key, prefix) \
PREFIXED_VECTOR_FLOAT_FEATURE_LIST(name, key); \
inline const bool CONCAT_STR2( \
Has, name)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR2(Has, name)(prefix, sequence); \
} \
inline const int CONCAT_STR3( \
Get, name, Size)(const tensorflow::SequenceExample& sequence) { \
return CONCAT_STR3(Get, name, Size)(prefix, sequence); \
} \
inline const proto_ns::RepeatedField<float>& CONCAT_STR3(Get, name, At)( \
const tensorflow::SequenceExample& sequence, int index) { \
return CONCAT_STR3(Get, name, At)(prefix, sequence, index); \
} \
inline void CONCAT_STR2(Clear, \
name)(tensorflow::SequenceExample * sequence) { \
CONCAT_STR2(Clear, name)(prefix, sequence); \
} \
inline void CONCAT_STR2(Add, name)(const ::std::vector<float>& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, values, sequence); \
} \
template <typename TContainer> \
inline void CONCAT_STR2(Add, name)(const TContainer& values, \
tensorflow::SequenceExample* sequence) { \
CONCAT_STR2(Add, name)(prefix, values, sequence); \
} \
inline const std::string CONCAT_STR3(Get, name, Key)() { \
return merge_prefix(prefix, key); \
}
#define VECTOR_FLOAT_FEATURE_LIST(name, key) \
FIXED_PREFIX_VECTOR_FLOAT_FEATURE_LIST(name, key, "");
} // namespace mediasequence
} // namespace mediapipe
#endif // MEDIAPIPE_TENSORFLOW_SEQUENCE_MEDIA_SEQUENCE_UTIL_H_