Skip to content

Commit

Permalink
impl(storage): static_assert to check Options for ParallelUploadFile (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
scotthart committed Sep 21, 2022
1 parent 74f4ba0 commit b3fc63c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
28 changes: 28 additions & 0 deletions google/cloud/internal/type_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_INTERNAL_TYPE_LIST_H

#include "google/cloud/version.h"
#include "absl/meta/type_traits.h"
#include <tuple>
#include <type_traits>
#include <utility>

namespace google {
Expand Down Expand Up @@ -85,6 +88,31 @@ struct TypeListCat<T1, T2, T...> {
using Type = TypeListCatT<TypeListCatT<T1, T2>, T...>;
};

template <typename List, typename T>
struct TypeListHasType;

template <typename... Us, typename T>
struct TypeListHasType<TypeList<Us...>, T>
: absl::disjunction<std::is_same<T, Us>...> {};

template <template <typename> class Predicate, typename List>
struct TypeListFilter;

template <template <typename> class Predicate, typename Head, typename... Ts>
struct TypeListFilter<Predicate, std::tuple<Head, Ts...>> {
using type = std::conditional_t<
Predicate<Head>::value,
decltype(std::tuple_cat(std::declval<std::tuple<Head>>(),
std::declval<typename TypeListFilter<
Predicate, std::tuple<Ts...>>::type>())),
typename TypeListFilter<Predicate, std::tuple<Ts...>>::type>;
};

template <template <typename> class Predicate>
struct TypeListFilter<Predicate, std::tuple<>> {
using type = std::tuple<>;
};

} // namespace internal
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace cloud
Expand Down
25 changes: 25 additions & 0 deletions google/cloud/storage/parallel_upload.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "google/cloud/storage/version.h"
#include "google/cloud/future.h"
#include "google/cloud/internal/filesystem.h"
#include "google/cloud/internal/type_list.h"
#include "google/cloud/status_or.h"
#include "absl/memory/memory.h"
#include "absl/types/optional.h"
Expand Down Expand Up @@ -1006,6 +1007,26 @@ struct PrepareParallelUploadApplyHelper {
std::string const& prefix;
};

using ParallelUploadFileSupportedOptions = google::cloud::internal::TypeList<
DestinationPredefinedAcl, EncryptionKey, IfGenerationMatch,
IfMetagenerationMatch, KmsKeyName, MaxStreams, MinStreamSize, QuotaUser,
UserIp, UserProject, WithObjectMetadata, UseResumableUploadSession>;

template <typename T>
using SupportsParallelOption =
google::cloud::internal::TypeListHasType<ParallelUploadFileSupportedOptions,
T>;

template <typename... Provided>
struct IsOptionSupportedWithParallelUpload
: std::integral_constant<
bool,
std::is_same<
std::tuple_size<std::tuple<Provided...>>,
std::tuple_size<typename google::cloud::internal::TypeListFilter<
SupportsParallelOption, std::tuple<Provided...>>::type>>::
value> {};

struct CreateParallelUploadShards {
/**
* Prepare a parallel upload of a given file.
Expand Down Expand Up @@ -1162,6 +1183,10 @@ StatusOr<ObjectMetadata> ParallelUploadFile(
Client client, std::string file_name, std::string bucket_name,
std::string object_name, std::string prefix, bool ignore_cleanup_failures,
Options&&... options) {
static_assert(
internal::IsOptionSupportedWithParallelUpload<Options...>::value,
"Provided Option not found in ParallelUploadFileSupportedOptions.");

auto shards = internal::CreateParallelUploadShards::Create(
std::move(client), std::move(file_name), std::move(bucket_name),
std::move(object_name), std::move(prefix),
Expand Down

0 comments on commit b3fc63c

Please sign in to comment.