aboutsummaryrefslogblamecommitdiffstats
path: root/library/cpp/deprecated/accessors/accessors_impl.h
blob: 6b2b987351f8a694d59b67ab794e380b0d374839 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12



                          





                                                                       
 
                                
 
                                                       
                                                                          
 




                                                             
 
                                               
                                    
 




                                                                 
 





                                                                 
                                                                                                  




                                                             
                                            
                                                      
                                   
                                                              
                                                                     

                                                         

             
                                                     
                                                                          
 




                                                             
 
                                             
                                  
 




                                                                 
 




                                                                 
 
                                                                                            
 


                                                             
 
                                            
                                                      
                                   
                                                              
                                                                     
 
                                                         
             










                                                       
                                    





















                                           
                                               
                                         
                                 
                                       
                                             






                                       
                                                                                                                                                 






                                   
                                  



















                                                  
                                           
                                       
                               
                                   
                                           








                                              
                                 













                                                  
                                                                                                






                                              

                                    


























                                                                              
                                           
                                      
                              
                                   
                                          










                                                                          

                                 




































                                                                                         
                                           
                                      
                              
                                   
                                          
                                  
                                       
                                              








                                                                                     
                                                        
                                                                          
 

                                                                                         





                                                                                                     
                 
 
                                                
                                     
 




                                                                                             
 




                                                                                             
 





                                                                                             
 




                                                                                             
 
                                               
                                          
                                  
                                       
                                              
                                      
                                           
                                                          
                                                   
 


                                                                                         
 
                                                                                                                                                   
 
                                                                                     


             
#pragma once

#include "memory_traits.h"

namespace NAccessors {
    namespace NPrivate {
        template <typename Ta>
        struct TMemoryAccessorBase {
            enum {
                SimpleMemory = TMemoryTraits<Ta>::SimpleMemory,
                ContinuousMemory = TMemoryTraits<Ta>::ContinuousMemory,
            };

            struct TBadAccessor;
        };

        template <typename Ta>
        struct TBegin: public TMemoryAccessorBase<Ta> {
            using TElementType = typename TMemoryTraits<Ta>::TElementType;

            template <typename Tb>
            struct TNoMemoryIndirectionBegin {
                static const TElementType* Get(const Tb& b) {
                    return (const TElementType*)&b;
                }
            };

            template <typename Tb>
            struct TIndirectMemoryRegionBegin {
                Y_HAS_MEMBER(Begin);
                Y_HAS_MEMBER(begin);

                template <typename Tc>
                struct TByBegin {
                    static const TElementType* Get(const Tc& b) {
                        return (const TElementType*)b.Begin();
                    }
                };

                template <typename Tc>
                struct TBybegin {
                    static const TElementType* Get(const Tc& b) {
                        return (const TElementType*)b.begin();
                    }
                };

                using TGet = std::conditional_t<THasBegin<Tb>::value, TByBegin<Tb>, TBybegin<Tb>>;

                static const TElementType* Get(const Tb& b) {
                    return TGet::Get(b);
                }
            };

            using TGet = std::conditional_t<
                TMemoryAccessorBase<Ta>::SimpleMemory,
                TNoMemoryIndirectionBegin<Ta>,
                std::conditional_t<
                    TMemoryAccessorBase<Ta>::ContinuousMemory,
                    TIndirectMemoryRegionBegin<Ta>,
                    typename TMemoryAccessorBase<Ta>::TBadAccessor>>;

            static const TElementType* Get(const Ta& b) {
                return TGet::Get(b);
            }
        };

        template <typename Ta>
        struct TEnd: public TMemoryAccessorBase<Ta> {
            using TElementType = typename TMemoryTraits<Ta>::TElementType;

            template <typename Tb>
            struct TNoMemoryIndirectionEnd {
                static const TElementType* Get(const Tb& b) {
                    return (const TElementType*)(&b + 1);
                }
            };

            template <typename Tb>
            struct TIndirectMemoryRegionEnd {
                Y_HAS_MEMBER(End);
                Y_HAS_MEMBER(end);

                template <typename Tc>
                struct TByEnd {
                    static const TElementType* Get(const Tc& b) {
                        return (const TElementType*)b.End();
                    }
                };

                template <typename Tc>
                struct TByend {
                    static const TElementType* Get(const Tc& b) {
                        return (const TElementType*)b.end();
                    }
                };

                using TGet = std::conditional_t<THasEnd<Tb>::value, TByEnd<Tb>, TByend<Tb>>;

                static const TElementType* Get(const Tb& b) {
                    return TGet::Get(b);
                }
            };

            using TGet = std::conditional_t<
                TMemoryAccessorBase<Ta>::SimpleMemory,
                TNoMemoryIndirectionEnd<Ta>,
                std::conditional_t<
                    TMemoryAccessorBase<Ta>::ContinuousMemory,
                    TIndirectMemoryRegionEnd<Ta>,
                    typename TMemoryAccessorBase<Ta>::TBadAccessor>>;

            static const TElementType* Get(const Ta& b) {
                return TGet::Get(b);
            }
        };

        template <typename Ta, bool Init>
        struct TClear: public TMemoryAccessorBase<Ta> {
            template <typename Tb>
            struct TNoMemoryIndirectionClear {
                static void Do(Tb& b) {
                    Zero(b);
                }
            };

            template <typename Tb>
            struct TIndirectMemoryRegionClear {
                Y_HAS_MEMBER(Clear);
                Y_HAS_MEMBER(clear);

                template <typename Tc>
                struct TByClear {
                    static void Do(Tc& b) {
                        b.Clear();
                    }
                };

                template <typename Tc>
                struct TByclear {
                    static void Do(Tc& b) {
                        b.clear();
                    }
                };

                template <typename Tc>
                struct TByNone {
                    static void Do(Tc& b) {
                        if (!Init)
                            b = Tc();
                    }
                };

                using TDo = std::conditional_t<
                    THasClear<Tb>::value,
                    TByClear<Tb>,
                    std::conditional_t<
                        THasclear<Tb>::value,
                        TByclear<Tb>,
                        TByNone<Tb>>>;

                static void Do(Tb& b) {
                    TDo::Do(b);
                }
            };

            using TDo = std::conditional_t<TMemoryAccessorBase<Ta>::SimpleMemory, TNoMemoryIndirectionClear<Ta>, TIndirectMemoryRegionClear<Ta>>;

            static void Do(Ta& b) {
                TDo::Do(b);
            }
        };

        template <typename Tb>
        struct TReserve {
            Y_HAS_MEMBER(Reserve);
            Y_HAS_MEMBER(reserve);

            template <typename Tc>
            struct TByReserve {
                static void Do(Tc& b, size_t sz) {
                    b.Reserve(sz);
                }
            };

            template <typename Tc>
            struct TByreserve {
                static void Do(Tc& b, size_t sz) {
                    b.reserve(sz);
                }
            };

            template <typename Tc>
            struct TByNone {
                static void Do(Tc&, size_t) {
                }
            };

            using TDo = std::conditional_t<
                THasReserve<Tb>::value,
                TByReserve<Tb>,
                std::conditional_t<
                    THasreserve<Tb>::value,
                    TByreserve<Tb>,
                    TByNone<Tb>>>;

            static void Do(Tb& b, size_t sz) {
                TDo::Do(b, sz);
            }
        };

        template <typename Tb>
        struct TResize {
            Y_HAS_MEMBER(Resize);
            Y_HAS_MEMBER(resize);

            template <typename Tc>
            struct TByResize {
                static void Do(Tc& b, size_t sz) {
                    b.Resize(sz);
                }
            };

            template <typename Tc>
            struct TByresize {
                static void Do(Tc& b, size_t sz) {
                    b.resize(sz);
                }
            };

            using TDo = std::conditional_t<THasResize<Tb>::value, TByResize<Tb>, TByresize<Tb>>;

            static void Do(Tb& b, size_t sz) {
                TDo::Do(b, sz);
            }
        };

        template <typename Tb>
        struct TAppend {
            Y_HAS_MEMBER(Append);
            Y_HAS_MEMBER(append);
            Y_HAS_MEMBER(push_back);

            template <typename Tc>
            struct TByAppend {
                using TElementType = typename TMemoryTraits<Tc>::TElementType;

                static void Do(Tc& b, const TElementType& val) {
                    b.Append(val);
                }
            };

            template <typename Tc>
            struct TByappend {
                using TElementType = typename TMemoryTraits<Tc>::TElementType;

                static void Do(Tc& b, const TElementType& val) {
                    b.append(val);
                }
            };

            template <typename Tc>
            struct TBypush_back {
                using TElementType = typename TMemoryTraits<Tc>::TElementType;

                static void Do(Tc& b, const TElementType& val) {
                    b.push_back(val);
                }
            };

            using TDo = std::conditional_t<
                THasAppend<Tb>::value,
                TByAppend<Tb>,
                std::conditional_t<
                    THasappend<Tb>::value,
                    TByappend<Tb>,
                    TBypush_back<Tb>>>;

            using TElementType = typename TMemoryTraits<Tb>::TElementType;

            static void Do(Tb& b, const TElementType& val) {
                TDo::Do(b, val);
            }
        };

        template <typename Tb>
        struct TAppendRegion {
            Y_HAS_MEMBER(Append);
            Y_HAS_MEMBER(append);
            Y_HAS_MEMBER(insert);

            template <typename Tc>
            struct TByAppend {
                using TElementType = typename TMemoryTraits<Tc>::TElementType;

                static void Do(Tc& b, const TElementType* beg, const TElementType* end) {
                    b.Append(beg, end);
                }
            };

            template <typename Tc>
            struct TByappend {
                using TElementType = typename TMemoryTraits<Tc>::TElementType;

                static void Do(Tc& b, const TElementType* beg, const TElementType* end) {
                    b.append(beg, end);
                }
            };

            template <typename Tc>
            struct TByinsert {
                using TElementType = typename TMemoryTraits<Tc>::TElementType;

                static void Do(Tc& b, const TElementType* beg, const TElementType* end) {
                    b.insert(b.end(), beg, end);
                }
            };

            template <typename Tc>
            struct TByNone {
                using TElementType = typename TMemoryTraits<Tc>::TElementType;

                static void Do(Tc& b, const TElementType* beg, const TElementType* end) {
                    for (const TElementType* it = beg; it != end; ++it)
                        TAppend<Tc>::Do(b, *it);
                }
            };

            using TDo = std::conditional_t<
                THasAppend<Tb>::value,
                TByAppend<Tb>,
                std::conditional_t<
                    THasappend<Tb>::value,
                    TByappend<Tb>,
                    std::conditional_t<
                        THasinsert<Tb>::value,
                        TByinsert<Tb>,
                        TByNone<Tb>>>>;

            using TElementType = typename TMemoryTraits<Tb>::TElementType;

            static void Do(Tb& b, const TElementType* beg, const TElementType* end) {
                TDo::Do(b, beg, end);
            }
        };

        template <typename Ta>
        struct TAssign: public TMemoryAccessorBase<Ta> {
            using TElementType = typename TMemoryTraits<Ta>::TElementType;

            template <typename Tb>
            struct TNoMemoryIndirectionAssign {
                static void Do(Tb& b, const TElementType* beg, const TElementType* end) {
                    if (sizeof(Tb) == sizeof(TElementType) && end - beg > 0) {
                        memcpy(&b, beg, sizeof(Tb));
                    } else if (end - beg > 0) {
                        memcpy(&b, beg, Min<size_t>((end - beg) * sizeof(TElementType), sizeof(Tb)));
                    } else {
                        Zero(b);
                    }
                }
            };

            template <typename Tb>
            struct TIndirectMemoryRegionAssign {
                Y_HAS_MEMBER(Assign);
                Y_HAS_MEMBER(assign);

                template <typename Tc>
                struct TByAssign {
                    static void Do(Tc& b, const TElementType* beg, const TElementType* end) {
                        b.Assign(beg, end);
                    }
                };

                template <typename Tc>
                struct TByassign {
                    static void Do(Tc& b, const TElementType* beg, const TElementType* end) {
                        b.assign(beg, end);
                    }
                };

                template <typename Tc>
                struct TByClearAppend {
                    static void Do(Tc& b, const TElementType* beg, const TElementType* end) {
                        TClear<Tc, false>::Do(b);
                        TAppendRegion<Tc>::Do(b, beg, end);
                    }
                };

                template <typename Tc>
                struct TByConstruction {
                    static void Do(Tc& b, const TElementType* beg, const TElementType* end) {
                        b = Tc(beg, end);
                    }
                };

                using TDo = std::conditional_t<
                    THasAssign<Tb>::value,
                    TByAssign<Tb>,
                    std::conditional_t<
                        THasassign<Tb>::value,
                        TByassign<Tb>,
                        std::conditional_t<
                            TMemoryTraits<Tb>::OwnsMemory,
                            TByClearAppend<Tb>,
                            TByConstruction<Tb>>>>;

                static void Do(Tb& b, const TElementType* beg, const TElementType* end) {
                    TDo::Do(b, beg, end);
                }
            };

            using TDo = std::conditional_t<TMemoryAccessorBase<Ta>::SimpleMemory, TNoMemoryIndirectionAssign<Ta>, TIndirectMemoryRegionAssign<Ta>>;

            static void Do(Ta& b, const TElementType* beg, const TElementType* end) {
                TDo::Do(b, beg, end);
            }
        };
    }
}