Commit 7ef3c1b2 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot 0

Remove ConditionallyExistent, because it violates the C++ spec

Summary:
[Folly] Remove `ConditionallyExistent`, because it violates the C++ spec.

The spec says that struct and class types occupy at least one byte. But the point of this class is to occupy zero bytes when the condition is false. That can't be made to work.

GCC and Clang support an extension allowing, in some cases, structs to occupy no space at all. But it violates the spec, and MSVC does not support the extension.

There is, sort of, the possibility of empty-base-class-optimization. But it will be very painful to use, and it will only work in some cases.

Since this is broken now, and fixing it would violate the C++ spec and break this under MSVC, it's better just to remove it.

Reviewed By: nbronson, Orvid

Differential Revision: D3696371

fbshipit-source-id: c475c6e15d9ff1bc4c44dc7e336ce74e6db640ef
parent efc54c28
/*
* Copyright 2016 Facebook, Inc.
*
* 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.
*/
#pragma once
#include <glog/logging.h>
#include <folly/Portability.h>
namespace folly {
template <typename T, bool Debug>
class ConditionallyExistent;
template <typename T>
class ConditionallyExistent<T, false> {
public:
static constexpr bool present() { return false; }
explicit ConditionallyExistent(const T&) {}
explicit ConditionallyExistent(T&&) {}
ConditionallyExistent(const ConditionallyExistent&) = delete;
ConditionallyExistent(ConditionallyExistent&&) = delete;
ConditionallyExistent& operator=(const ConditionallyExistent&) = delete;
ConditionallyExistent& operator=(ConditionallyExistent&&) = delete;
template <typename F>
void with(const F&&) {}
};
template <typename T>
class ConditionallyExistent<T, true> {
public:
static constexpr bool present() { return true; }
explicit ConditionallyExistent(const T& v) : value_(v) {}
explicit ConditionallyExistent(T&& v) : value_(std::move(v)) {}
ConditionallyExistent(const ConditionallyExistent&) = delete;
ConditionallyExistent(ConditionallyExistent&&) = delete;
ConditionallyExistent& operator=(const ConditionallyExistent&) = delete;
ConditionallyExistent& operator=(ConditionallyExistent&&) = delete;
template <typename F>
void with(F&& f) {
f(value_);
}
private:
T value_;
};
template <typename T>
using ExistentIfDebug = ConditionallyExistent<T, kIsDebug>;
}
......@@ -44,7 +44,6 @@ nobase_follyinclude_HEADERS = \
ClockGettimeWrappers.h \
ConcurrentSkipList.h \
ConcurrentSkipList-inl.h \
ConditionallyExistent.h \
ContainerTraits.h \
Conv.h \
CppAttributes.h \
......
/*
* Copyright 2016 Facebook, Inc.
*
* 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.
*/
#include <folly/ConditionallyExistent.h>
#include <gtest/gtest.h>
using namespace std;
using namespace folly;
namespace {
class ConditionallyExistentTest : public testing::Test {};
}
TEST_F(ConditionallyExistentTest, WhenConditionFalse) {
folly::ConditionallyExistent<string, false> foobar("hello world");
EXPECT_FALSE(foobar.present());
bool called = false;
foobar.with([&](const string&) { called = true; });
EXPECT_FALSE(called);
}
TEST_F(ConditionallyExistentTest, WhenConditionTrue) {
folly::ConditionallyExistent<string, true> foobar("hello world");
EXPECT_TRUE(foobar.present());
bool called = false;
foobar.with([&](const string&) { called = true; });
EXPECT_TRUE(called);
}
......@@ -181,10 +181,6 @@ string_test_SOURCES = StringTest.cpp
string_test_LDADD = libfollytestmain.la
TESTS += string_test
conditionally_existent_test_SOURCES = ConditionallyExistentTest.cpp
conditionally_existent_test_LDADD = libfollytestmain.la
TESTS += conditionally_existent_test
producer_consumer_queue_test_SOURCES = ProducerConsumerQueueTest.cpp
producer_consumer_queue_test_LDADD = libfollytestmain.la
TESTS += producer_consumer_queue_test
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment