Skip to content

Instantly share code, notes, and snippets.

@zyxar
Created May 25, 2016 14:51
Show Gist options
  • Save zyxar/10a4fd8344c1007f2a5aae5892e4b101 to your computer and use it in GitHub Desktop.
Save zyxar/10a4fd8344c1007f2a5aae5892e4b101 to your computer and use it in GitHub Desktop.
shared_arguments
// Copyright 2016 Markus Tzoe
// 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 "Argument.h"
namespace cross {
template <class P>
Argument<P>::Argument(P* p)
: payload_{ p }
{
}
template <class P>
template <class D>
Argument<P>::Argument(P* p, D del)
: payload_{ p, del }
{
}
template <class P>
Argument<P>::~Argument() {}
template <class P>
Argument<P>::Argument(const char* rhs)
: payload_{ new std::string{ rhs } }
{
}
template <class P>
Argument<P>::Argument(const std::string& rhs)
: payload_{ new std::string{ rhs } }
{
}
template <class P>
Argument<P>::Argument(bool rhs)
: payload_{ new bool{ rhs } }
{
}
template <class P>
Argument<P>::Argument(int64_t rhs)
: payload_{ new int64_t{ rhs } }
{
}
template <class P>
Argument<P>::Argument(uint64_t rhs)
: payload_{ new uint64_t{ rhs } }
{
}
template <class P>
Argument<P>::Argument(int32_t rhs)
: payload_{ new int32_t{ rhs } }
{
}
template <class P>
Argument<P>::Argument(uint32_t rhs)
: payload_{ new uint32_t{ rhs } }
{
}
template <class P>
Argument<P>::Argument(double rhs)
: payload_{ new double{ rhs } }
{
}
template <class P>
Argument<P>::Argument(const Argument& rhs)
: payload_{ rhs.payload_ }
{
}
template <class P>
Argument<P>::operator bool() const noexcept
{
return payload_.operator bool();
}
template <class P>
void Argument<P>::swap(Argument& x) noexcept
{
Argument<P>(x).swap(*this);
}
template <class P>
void Argument<P>::reset() noexcept { payload_.reset(); }
template <class P>
void Argument<P>::reset(P* p)
{
payload_.reset(p);
}
template <class P>
P& Argument<P>::operator*() const noexcept
{
return *payload_;
}
template <class P>
P* Argument<P>::operator->() const noexcept
{
return payload_.operator->();
}
template <class P>
Argument<P>& Argument<P>::operator=(const Argument& rhs)
{
payload_ = rhs.payload_;
return *this;
}
} // namespace cross
#if 1
#include <iostream>
int main(int argc, char const* argv[])
{
cross::Argument<int> a{ new int{ 1 },
[&a](int* p) {
std::cout << "a [deleter called] " << &a << "\n";
delete p;
} };
cross::Argument<std::string> b{ new std::string{ "HOLA" },
[&b](std::string* p) {
std::cout << "b [deleter called] " << &b << "\n";
delete p;
} };
cross::Argument<int> c{ a };
c.reset();
cross::inspect(std::cout, 1, "2", 3.0, true, false, a, b);
return 0;
}
#endif
// Copyright 2016 Markus Tzoe
// 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 Argument_h
#define Argument_h
#include <memory>
#include <sstream>
#include <string>
namespace cross {
template <class P>
class Argument {
private:
std::shared_ptr<P> payload_;
Argument() = delete;
public:
~Argument();
explicit Argument(P* p);
template <class D>
explicit Argument(P* p, D del);
Argument(const char* rhs);
Argument(const std::string& rhs);
Argument(bool rhs);
Argument(int64_t rhs);
Argument(uint64_t rhs);
Argument(int32_t rhs);
Argument(uint32_t rhs);
Argument(double rhs);
Argument(const Argument& rhs);
Argument& operator=(const Argument& rhs);
explicit operator bool() const noexcept;
void swap(Argument&) noexcept;
void reset() noexcept;
void reset(P* p);
P& operator*() const noexcept;
P* operator->() const noexcept;
};
template <class P>
std::ostream& operator<<(std::ostream& os, const Argument<P>& argv)
{
if (argv)
os << *argv;
return os;
}
template <class P>
void inspect(std::ostream& os, const P& p)
{
os << __PRETTY_FUNCTION__ << ": " << p << std::endl;
}
template <class P>
void inspect(std::ostream& os, const Argument<P>& p)
{
if (p)
os << __PRETTY_FUNCTION__ << ": " << p << std::endl;
}
template <class P, class... Args>
void inspect(std::ostream& os, const P& p, const Args&... args) // recursive
{
inspect(os, p);
inspect(os, args...);
}
} // namespace cross
#endif // Argument_h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment