Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 51 additions & 11 deletions module-1/homework/TypeTraits/type_traits/is_copy_constructible.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,69 @@ struct LibCppIsConstructible;

template <typename Derived, typename Base>
struct IsInvalidBaseToDerivedCast {
// Your code goes here
using derived = uncvref_t<Derived>;
using base = uncvref_t<Base>;
using value =
std::integral_constant<bool, !std::is_same_v<base, derived> &&
std::is_base_of_v<base, derived> &&
!LibCppIsConstructible<derived, base>::type::value>;
};

template <typename To, typename From>
struct IsInvalidLvalueToRvalueCast : std::false_type {
// Your code goes here
};
struct IsInvalidLvalueToRvalueCast : std::false_type {};

template <typename RefTo, typename RefFrom>
struct IsInvalidLvalueToRvalueCast<RefTo&&, RefFrom&> {
// Your code goes here
using to = uncvref_t<RefTo>;
using from = uncvref_t<RefFrom>;
using value =
std::integral_constant<bool, std::is_same_v<from, to> && std::is_base_of_v<to, from>>;
};

struct IsConstructibleHelper {
// Your code goes here
template <typename To>
static void ImplicitCast(To);

template <typename To, typename From, typename = decltype(ImplicitCast<To>(Declval<From>()))>
static std::true_type Castable(int);

template <typename To, typename From, typename = decltype(static_cast<To>(Declval<From>()))>
static std::integral_constant<bool, !IsInvalidBaseToDerivedCast<To, From>::value &&
!IsInvalidLvalueToRvalueCast<To, From>::value>
Castable(double);

template <typename, typename>
static std::false_type Castable(...);

template <typename T, typename... Args, typename = decltype(T(Declval<Args>()...))>
static std::true_type Constructible(int);

template <typename, typename>
static std::false_type Constructible(...);
};

template <typename T, typename... Args>
struct LibCppIsConstructible {
using type = decltype(IsConstructibleHelper::Constructible<T, Args...>(0));
};

template <typename T, typename Arg>
struct LibCppIsConstructible<T, Arg> {
using type = decltype(IsConstructibleHelper::Constructible<T, Arg>(0));
};

// LibCppIsConstructible - partial specializations
// Your code goes here
// LibCppIsConstructible - partial specializations
template <typename T, typename Arg>
struct LibCppIsConstructible<T&, Arg> {
using type = decltype(IsConstructibleHelper::Castable<T&, Arg>(0));
};

template <typename T, typename Arg>
struct LibCppIsConstructible<T&&, Arg> {
using type = decltype(IsConstructibleHelper::Castable<T&&, Arg>(0));
};

template <typename T, typename... Args>
struct IsConstructible : // Your code goes here {...}
struct IsConstructible : LibCppIsConstructible<T, Args...>::type {};

template <typename T>
struct IsCopyConstructible : // Your code goes here {...}
struct IsCopyConstructible : LibCppIsConstructible<T, const T&>::type {};
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,31 @@
template <bool, bool, typename T, typename... Args>
struct LibCppIsNoThrowConstructible;

// LibCppIsNoThrowConstructible - partial specializations
// Your code goes here
// LibCppIsNoThrowConstructible - partial specializations
template <typename T, typename... Args>
struct LibCppIsNoThrowConstructible<true, false, T, Args...> {
using type = std::integral_constant<bool, noexcept(T(Declval<Args>()...))>;
};

template <typename T, typename Arg>
struct LibCppIsNoThrowConstructible<true, true, T, Arg> {
using type =
std::integral_constant<bool,
noexcept(IsConstructibleHelper::ImplicitCast<T>(Declval<Arg>()))>;
};

template <bool IsReference, typename T, typename... Args>
struct LibCppIsNoThrowConstructible<false, IsReference, T, Args...> {
using type = std::false_type;
};

template <typename T, typename... Args>
struct IsNoThrowConstructible : // Your code goes here {...}
struct IsNoThrowConstructible
: LibCppIsNoThrowConstructible<IsConstructible<T, Args...>::value, std::is_reference_v<T>, T,
Args...>::type {};

template <typename T, std::size_t N>
struct IsNoThrowConstructible<T[N]> : // Your code goes here {...}
template <typename T, size_t N>
struct IsNoThrowConstructible<T[N]>
: LibCppIsNoThrowConstructible<IsConstructible<T>::value, std::is_reference_v<T>, T>::type {};

template <typename T>
struct IsNoThrowMoveConstructible : // Your code goes here {...}
struct IsNoThrowMoveConstructible : IsNoThrowConstructible<T, T&&> {};
22 changes: 12 additions & 10 deletions module-1/homework/TypeTraits/type_traits/move_if_noexcept.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@
#include "utility.h"

template <bool condition, typename T, typename F>
struct Conditional {
// Your code goes here
};
struct Conditional;

// Conditional - partial specialization
// Your code goes here
// Conditional - partial specialization
template <typename T, typename F>
struct Conditional<false, T, F> {
using type = F;
};

template <typename T, typename F>
struct Conditional<true, T, F> {
using type = T;
};

template <bool condition, typename T, typename F>
using conditional_v = // Your code goes here
using conditional_v = typename Conditional<condition, T, F>::type;

// MoveIfNoExcept
// Your code goes here
// MoveIfNoExcept
template <typename T>
typename Conditional<!IsNoThrowMoveConstructible<T>::value && IsCopyConstructible<T>::value,
const T&, T&&>::type
MoveIfNoExcept(T& x) noexcept {
return std::move(x);
}
75 changes: 67 additions & 8 deletions module-1/homework/TypeTraits/type_traits/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,89 @@
#include <type_traits>
#include <utility>

template <typename T>
struct RemoveConst {
using type = T;
};

template <typename T>
struct RemoveConst<T const> {
using type = T;
};

template <typename T>
using remove_const_t = typename RemoveConst<T>::type;

template <typename T>
struct RemoveVolatile {
using type = T;
};

template <typename T>
struct RemoveVolatile<T volatile> {
using type = T;
};

template <typename T>
using remove_volatile_t = typename RemoveVolatile<T>::type;

template <typename T>
struct RemoveReference {
using type = T;
};

template <typename T>
struct RemoveReference<T&> {
using type = T;
};

template <typename T>
struct RemoveReference<T&&> {
using type = T;
};

template <typename T>
using remove_reference_t = typename RemoveReference<T>::type;

template <typename T>
struct Uncv {
using type = remove_const_t<remove_volatile_t<T>>;
};

template <typename T>
using uncv_t = typename Uncv<T>::type;

template <typename T>
struct Uncvref {
// Your code goes here
using type = uncv_t<remove_reference_t<T>>;
};

template <typename T>
using uncvref_t = // Your code goes here
using uncvref_t = typename Uncvref<T>::type;

template <typename T>
struct AddConst {
using type = // Your code goes here
using type = const T;
};

template <typename T>
using add_const_t = // Your code goes here
using add_const_t = typename AddConst<T>::type;

template <typename T>
struct AddLvalueReference : // Your code goes here
struct AddLvalueReference {
using type = T&;
};

template <typename T>
struct AddRvalueReference {
using type = T&&;
};

template <typename T>
struct AddRvalueReference : // Your code goes here
using add_lvalue_reference_t = typename AddLvalueReference<T>::type;

template <typename T>
using add_lvalue_reference_t = // Your code goes here
using add_rvalue_reference_t = typename AddRvalueReference<T>::type;

template <typename T>
using add_rvalue_reference_t = // Your code goes here
add_rvalue_reference_t<T> Declval() noexcept;